<!DOCTYPE html>
<html lang="zh-CN">
	<head>
		<meta charset="UTF-8">
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<title>沮爹模拟器开源教学网页</title>
		<link rel="stylesheet" href="head.css">
	</head>
	<body>

		<button id="backToTopBtn">回到顶部</button>

		<div class="header-placeholder"></div>
		<section class="hero-section">
			<h1 class="hero-title">模拟器开源教学网页</h1>
			<h3 class="hero-title">将鼠标悬停在函数名上查看完整源代码</h3>
			<div class="nav-buttons">
				<button class="nav-button"><a href="index.html">返回新版主页</a></button>
				<button class="nav-button"><a href="indexjd.html">返回经典版主页</a></button>
			</div>
		</section>
		<div class="instructions">
			<h3>使用说明</h3>
			<p>将鼠标悬停在函数名，配套css上，会显示该函数和配套css的完整源代码。</p>
			<p>每个函数下方添加了<strong>配套CSS</strong>部分，同样可以通过悬停查看CSS源代码。</p>
		</div>

		<!-- 核心游戏功能 -->
		<div class="function-category">一、核心游戏功能</div>

		<!-- 1. 牌堆管理系统 -->
		<div class="function-item">
			<div class="function-name">
				initializeDeck()
				<div class="function-tooltip">
					<strong>initializeDeck()</strong> - 初始化牌堆
					<code>function initializeDeck() {
						// 清空日志
						document.getElementById('log').innerHTML = '';
						log("牌堆初始化开始");

						// 重置所有数组
						deck = [];
						drawnCards = [];
						discardPile = [];
						hand = [];

						// 清空UI显示
						document.getElementById('deck').innerHTML = '';

						// 重置游戏状态
						reshuffleUsed = 0;
						phase = '';
						lastUsedCard = null;
						peachCount = 1;
						wineCount = 1;

						// 使用预定义的standardDeck生成牌堆
						standardDeck.forEach(card => {
						// 处理每张卡牌的花色和点数
						card.suits.forEach(suitStr => {
						// 使用正则匹配花色和点数
						const match = suitStr.match(/^([♠♥♣♦]️?)([JQKA]|\d+)$/);
						if (match) {
						const suitPart = match[1];
						let point = match[2];

						// 点数转换
						if (point === 'J') point = 11;
						else if (point === 'Q') point = 12;
						else if (point === 'K') point = 13;
						else if (point === 'A') point = 1;
						else point = parseInt(point);

						// 根据卡牌数量生成多张牌
						for (let i = 0; i < card.count; i++) { // 生成唯一ID并添加到牌堆 deck.push({ name: card.name, suit:
							suitPart, point: point, uid: CryptoJS.lib.WordArray.random(16).toString() }); } } }); }); //
							重置武器状态 currentWeapon=null; killCount=2; hasZhugeLianNu=false; updateStatus(); // 更新状态显示 //
							洗牌并开始游戏 shuffleDeck(); generateDeckMD5(); updateMD5Display(); generateDeckAES();
							updateAESDisplay(); updateRemaining(); startGame(); log("牌堆初始化完成"); }</code>
				</div>
			</div>
			<div class="function-description">
				初始化游戏牌堆，重置所有游戏状态变量，生成新的牌堆并开始游戏。
			</div>

			<div class="css-section">
				<span class="css-name">
					配套CSS
					<div class="css-tooltip">
						<strong>牌堆管理系统CSS</strong>
						<code>/* 卡牌基础样式 */
							.card {
							background-color: #f0f0f0;
							border: 1px solid #ccc;
							padding: 8px;
							margin: 4px;
							display: inline-block;
							width: 130px;
							text-align: center;
							border-radius: 4px;
							box-shadow: 0 2px 4px rgba(0,0,0,0.1);
							transition: all 0.2s ease;
							}

							.card:hover {
							transform: translateY(-3px);
							box-shadow: 0 4px 8px rgba(0,0,0,0.15);
							}

							/* 牌堆区域样式 */
							#deck {
							margin-top: 15px;
							padding: 10px;
							background: #f8f9fa;
							border: 1px solid #e0e0e0;
							border-radius: 6px;
							min-height: 100px;
							}

							/* 剩余牌堆区域样式 */
							#remaining {
							margin-top: 15px;
							padding: 10px;
							background: #fff8e1;
							border: 1px solid #ffd54f;
							border-radius: 6px;
							min-height: 100px;
							}

							/* 手牌区域样式 */
							#hand {
							margin: 15px 0;
							padding: 15px;
							background: #e8f5e9;
							border: 1px solid #c8e6c9;
							border-radius: 6px;
							min-height: 150px;
							}

							/* 高亮状态 */
							.highlight {
							background-color: #fff9c4;
							border: 2px solid #ffd600;
							box-shadow: 0 0 10px rgba(255, 214, 0, 0.5);
							}

							/* 禁用状态 */
							.disabled {
							opacity: 0.5;
							pointer-events: none;
							cursor: not-allowed;
							}</code>
					</div>
				</span>
			</div>

			<div class="key-points">
				<h3>关键技术点</h3>
				<ul>
					<li>使用Fisher-Yates洗牌算法实现随机牌堆</li>
					<li>卡牌对象模型包含名称、花色、点数和唯一ID</li>
					<li>支持多种卡牌类型：基本牌、锦囊牌、装备牌</li>
				</ul>
			</div>
		</div>

		<!-- 洗牌函数 -->
		<div class="function-item">
			<div class="function-name">
				shuffleDeck()
				<div class="function-tooltip">
					<strong>shuffleDeck()</strong> - 洗牌函数
					<code>function shuffleDeck() {
						log("开始洗牌...");

						// 使用Fisher-Yates洗牌算法
						for (let i = deck.length - 1; i > 0; i--) {
						// 使用加密API获取随机索引
						const randomBuffer = new Uint32Array(1);
						window.crypto.getRandomValues(randomBuffer);
						const j = randomBuffer[0] % (i + 1);

						// 交换位置
						[deck[i], deck[j]] = [deck[j], deck[i]];
						}

						// 添加洗牌动画效果
						const deckElement = document.getElementById('deck');
						deckElement.classList.add('shuffling');

						// 更新UI显示
						updateDeckDisplay();

						// 生成新的加密标识
						generateDeckMD5();
						generateDeckAES();

						// 移除动画类
						setTimeout(() => {
						deckElement.classList.remove('shuffling');
						log("洗牌完成！牌堆已重新随机排序");
						}, 1200);
						}</code>
				</div>
			</div>
			<div class="function-description">
				使用Fisher-Yates算法随机打乱牌堆顺序，更新加密标识和状态显示。
			</div>

			<div class="css-section">
				<span class="css-name">
					配套CSS
					<div class="css-tooltip">
						<strong>洗牌动画CSS</strong>
						<code>/* 洗牌动画容器 */
							.shuffling {
							position: relative;
							animation: deckShuffle 1.2s cubic-bezier(0.4, 0, 0.2, 1);
							filter: drop-shadow(0 0 12px rgba(255, 215, 64, 0.6));
							}

							/* 单张卡牌的洗牌动画 */
							.card.shuffle-item {
							animation: cardShuffle 0.8s ease-in-out both;
							transform-origin: 50% 100%;
							}

							/* 牌堆整体洗牌动画 */
							@keyframes deckShuffle {
							0% {
							transform: translateY(0) rotateZ(0deg);
							opacity: 1;
							}
							30% {
							transform: translateY(-20px) rotateZ(-5deg);
							opacity: 0.9;
							}
							70% {
							transform: translateY(10px) rotateZ(5deg);
							opacity: 0.95;
							}
							100% {
							transform: translateY(0) rotateZ(0deg);
							opacity: 1;
							}
							}

							/* 单张卡牌洗牌动画 */
							@keyframes cardShuffle {
							0% {
							transform: rotateZ(0deg) scale(1);
							z-index: 1;
							}
							25% {
							transform: rotateZ(-15deg) scale(1.05);
							z-index: 2;
							}
							50% {
							transform: rotateZ(15deg) scale(0.95);
							filter: brightness(1.2);
							}
							75% {
							transform: rotateZ(-10deg) scale(1.02);
							filter: brightness(1.1);
							}
							100% {
							transform: rotateZ(0deg) scale(1);
							z-index: 1;
							}
							}

							/* 减少运动偏好设置 */
							@media (prefers-reduced-motion: no-preference) {
							.shuffling,
							.card.shuffle-item {
							will-change: transform, filter;
							backface-visibility: hidden;
							}
							}</code>
					</div>
				</span>
			</div>

			<div class="key-points">
				<h3>关键技术点</h3>
				<ul>
					<li>使用Fisher-Yates洗牌算法实现高效随机化</li>
					<li>采用加密API生成安全随机数（window.crypto.getRandomValues）</li>
					<li>添加视觉动画效果增强用户体验</li>
					<li>支持减少运动偏好设置（prefers-reduced-motion）</li>
				</ul>
			</div>
		</div>

		<!-- 抽牌函数 -->
		<div class="function-item">
			<div class="function-name">
				drawCards(count)
				<div class="function-tooltip">
					<strong>drawCards(count)</strong> - 抽牌函数
					<code>function drawCards(count) {
						log(`开始抽取 ${count} 张牌...`);

						// 检查牌堆是否足够
						if (deck.length < count) { log("牌堆数量不足，自动重新洗牌弃牌堆"); reshuffleDiscardPile(); } const drawn=[];
							for (let i=0; i < count; i++) { if (deck.length===0) { log("牌堆已空，无法继续抽牌"); break; } //
							从牌堆顶部取牌 const card=deck.shift(); drawn.push(card); drawnCards.push(card); // 添加到手牌
							hand.push(card); // 添加动画效果 animateCardDraw(card); } // 更新UI和状态 updateHandDisplay();
							updateRemaining(); generateDeckMD5(); updateMD5Display(); log(`成功抽取 ${drawn.length} 张牌`); //
							检查是否抽到诸葛连弩 const zhugeCard=drawn.find(card=> card.name === "诸葛连弩");
							if (zhugeCard) {
							hasZhugeLianNu = true;
							log("★ 抽到诸葛连弩，杀次数上限+1");
							updateStatus();
							}

							return drawn;
							}

							// 辅助函数：卡片抽取动画
							function animateCardDraw(card) {
							const cardElement = document.createElement('div');
							cardElement.className = 'card draw-animation';
							cardElement.textContent = `${card.name} (${card.suit}${card.point})`;
							cardElement.dataset.uid = card.uid;

							// 添加到动画容器
							const animationContainer = document.getElementById('animation-container');
							animationContainer.appendChild(cardElement);

							// 动画结束后移除元素
							setTimeout(() => {
							cardElement.remove();
							}, 1200);
							}</code>
				</div>
			</div>
			<div class="function-description">
				从牌堆顶部抽取指定数量的卡牌，添加到玩家手牌中。
			</div>

			<div class="css-section">
				<span class="css-name">
					配套CSS
					<div class="css-tooltip">
						<strong>抽牌动画CSS</strong>
						<code>/* 抽牌动画容器 */
							#animation-container {
							position: fixed;
							top: 0;
							left: 0;
							width: 100%;
							height: 100%;
							pointer-events: none;
							z-index: 2000;
							overflow: visible;
							}

							/* 抽牌动画 */
							.card.draw-animation {
							position: absolute;
							top: 50%;
							left: 50%;
							z-index: 2001;
							animation: drawCard 1.2s cubic-bezier(0.68, -0.55, 0.27, 1.55) forwards;
							transform-origin: center;
							box-shadow: 0 0 20px rgba(255, 215, 0, 0.7);
							}

							/* 抽牌动画关键帧 */
							@keyframes drawCard {
							0% {
							transform: translate(-50%, -50%) scale(0.8) rotateY(0deg);
							opacity: 0;
							filter: blur(2px);
							}
							30% {
							transform: translate(-50%, -150%) scale(1.2) rotateY(180deg);
							opacity: 1;
							filter: blur(0);
							box-shadow: 0 0 30px rgba(255, 215, 0, 0.9);
							}
							70% {
							transform: translate(calc(-50% + 200px), -50%) scale(1.1) rotateY(360deg);
							opacity: 0.9;
							}
							100% {
							transform: translate(calc(-50% + 400px), 100px) scale(1) rotateY(720deg);
							opacity: 0;
							}
							}

							/* 特殊卡牌高亮 */
							.card.draw-animation[data-card-type="weapon"] {
							animation: drawWeapon 1.2s ease-in-out forwards;
							background: linear-gradient(45deg, #ffeb3b, #ff9800);
							box-shadow: 0 0 25px rgba(255, 152, 0, 0.8);
							}

							@keyframes drawWeapon {
							0% {
							transform: translate(-50%, -50%) scale(0.8);
							opacity: 0;
							}
							50% {
							transform: translate(-50%, -50%) scale(1.3);
							opacity: 1;
							box-shadow: 0 0 40px rgba(255, 152, 0, 0.9);
							}
							100% {
							transform: translate(calc(-50% + 400px), 100px) scale(1);
							opacity: 0;
							}
							}

							/* 减少运动设置 */
							@media (prefers-reduced-motion: reduce) {
							.card.draw-animation {
							animation: none !important;
							opacity: 0 !important;
							}
							}</code>
					</div>
				</span>
			</div>

			<div class="key-points">
				<h3>关键技术点</h3>
				<ul>
					<li>自动检测牌堆数量不足时重新洗牌弃牌堆</li>
					<li>支持减少运动偏好设置（prefers-reduced-motion）</li>
					<li>抽到武器卡牌时自动更新游戏状态</li>
				</ul>
			</div>
		</div>
		<!-- 2. 游戏阶段管理 -->
		<div class="function-item">
			<div class="function-name">
				startGame()
				<div class="function-tooltip">
					<strong>startGame()</strong> - 开始游戏
					<code>function startGame() {
						log("游戏开始！");

						// 重置游戏状态
						phase = 'preparation';
						killCount = 2; // 初始杀次数
						hasZhugeLianNu = false;
						currentWeapon = null;

						// 清除手牌和弃牌堆
						hand = [];
						discardPile = [];

						// 更新状态显示
						updateStatus();

						// 添加游戏开始动画
						const gameArea = document.getElementById('game-area');
						gameArea.classList.add('game-starting');

						// 显示开始动画
						setTimeout(() => {
						// 抽取起始手牌（4张）
						drawCards(4);

						// 进入准备阶段
						setPhase('preparation');
						log("准备阶段，请等待...");

						// 移除动画类
						gameArea.classList.remove('game-starting');
						}, 1500);
						}

						// 设置游戏阶段
						function setPhase(newPhase) {
						phase = newPhase;
						const phaseElement = document.getElementById('phase-indicator');

						// 更新阶段显示
						phaseElement.textContent = `当前阶段: ${getPhaseName(newPhase)}`;
						phaseElement.className = `phase ${newPhase}`;

						// 根据阶段更新按钮状态
						updateButtonStates();

						log(`进入${getPhaseName(newPhase)}阶段`);
						}

						// 获取阶段名称
						function getPhaseName(phaseCode) {
						const phases = {
						'preparation': '准备',
						'draw': '摸牌',
						'play': '出牌',
						'discard': '弃牌',
						'end': '结束'
						};
						return phases[phaseCode] || phaseCode;
						}

						// 更新按钮状态
						function updateButtonStates() {
						const drawBtn = document.getElementById('drawBtn');
						const endBtn = document.getElementById('endBtn');

						// 根据阶段启用/禁用按钮
						drawBtn.disabled = phase !== 'draw';
						endBtn.disabled = phase !== 'play';

						// 添加视觉反馈
						if (phase === 'draw') {
						drawBtn.classList.add('phase-active');
						} else {
						drawBtn.classList.remove('phase-active');
						}
						}</code>
				</div>
			</div>
			<div class="function-description">
				初始化游戏状态，进入准备阶段，抽取起始手牌。
			</div>

			<div class="css-section">
				<span class="css-name">
					配套CSS
					<div class="css-tooltip">
						<strong>游戏阶段CSS</strong>
						<code>/* 游戏区域开始动画 */
							.game-starting {
							position: relative;
							overflow: hidden;
							}

							.game-starting::before {
							content: '';
							position: absolute;
							top: 0;
							left: 0;
							right: 0;
							bottom: 0;
							background: linear-gradient(45deg, #ff5722, #ff9800, #ffeb3b, #4caf50);
							z-index: 100;
							animation: gameStartGradient 1.5s ease-in-out forwards;
							opacity: 0.8;
							}

							@keyframes gameStartGradient {
							0% {
							transform: scale(0) rotate(0deg);
							opacity: 0;
							}
							50% {
							transform: scale(2) rotate(180deg);
							opacity: 0.9;
							}
							100% {
							transform: scale(4) rotate(360deg);
							opacity: 0;
							}
							}

							/* 阶段指示器 */
							.phase {
							display: inline-block;
							padding: 6px 12px;
							border-radius: 20px;
							font-weight: bold;
							margin: 10px 0;
							transition: all 0.3s ease;
							box-shadow: 0 2px 5px rgba(0,0,0,0.1);
							}

							/* 不同阶段的颜色 */
							.phase.preparation {
							background: #2196F3;
							color: white;
							}

							.phase.draw {
							background: #4CAF50;
							color: white;
							}

							.phase.play {
							background: #FF9800;
							color: white;
							}

							.phase.discard {
							background: #F44336;
							color: white;
							}

							.phase.end {
							background: #9C27B0;
							color: white;
							}

							/* 阶段按钮 */
							.phase-button {
							padding: 8px 16px;
							border-radius: 4px;
							font-weight: bold;
							cursor: pointer;
							transition: all 0.2s;
							margin: 0 5px;
							border: none;
							box-shadow: 0 2px 4px rgba(0,0,0,0.2);
							}

							/* 激活阶段的按钮 */
							.phase-active {
							transform: scale(1.05);
							box-shadow: 0 0 15px rgba(255, 193, 7, 0.8);
							animation: pulse 1.5s infinite;
							}

							@keyframes pulse {
							0% {
							box-shadow: 0 0 0 0 rgba(255, 193, 7, 0.7);
							}
							70% {
							box-shadow: 0 0 0 12px rgba(255, 193, 7, 0);
							}
							100% {
							box-shadow: 0 0 0 0 rgba(255, 193, 7, 0);
							}
							}

							/* 禁用按钮样式 */
							.phase-button:disabled {
							opacity: 0.5;
							cursor: not-allowed;
							transform: none;
							box-shadow: none;
							animation: none;
							}</code>
					</div>
				</span>
			</div>

			<div class="key-points">
				<h3>关键技术点</h3>
				<ul>
					<li>多阶段游戏状态管理（准备、摸牌、出牌、弃牌、结束）</li>
					<li>动态按钮状态控制（根据阶段启用/禁用按钮）</li>
					<li>视觉反馈系统（阶段指示器颜色变化）</li>
					<li>游戏开始动画增强用户体验</li>
					<li>脉冲动画效果提示当前可操作阶段</li>
				</ul>
			</div>
		</div>

		<div class="function-item">
			<div class="function-name">
				drawPhase()
				<div class="function-tooltip">
					<strong>drawPhase()</strong> - 进入摸牌阶段
					<code>function drawPhase() {
						// 确保在正确的阶段
						if (phase !== 'preparation') {
						log("无法进入摸牌阶段：当前阶段错误");
						return;
						}

						log("进入摸牌阶段...");
						setPhase('draw');

						// 添加阶段动画效果
						const phaseIndicator = document.getElementById('phase-indicator');
						phaseIndicator.classList.add('phase-transition');

						// 抽取3张牌
						setTimeout(() => {
						drawCards(3);

						// 更新阶段按钮状态
						updateButtonStates();

						// 进入出牌阶段
						setTimeout(() => {
						setPhase('play');
						log("摸牌完成，进入出牌阶段");
						phaseIndicator.classList.remove('phase-transition');
						}, 1000);
						}, 500);

						// 更新状态显示
						updateStatus();
						}</code>
				</div>
			</div>
			<div class="function-description">
				进入摸牌阶段，抽取3张牌并更新游戏阶段状态。
			</div>

			<div class="css-section">
				<span class="css-name">
					配套CSS
					<div class="css-tooltip">
						<strong>阶段按钮CSS</strong>
						<code>/* 摸牌阶段按钮 */
							#drawBtn {
							background: linear-gradient(to bottom, #4CAF50, #2E7D32);
							color: white;
							border: none;
							padding: 10px 20px;
							border-radius: 4px;
							font-weight: bold;
							cursor: pointer;
							transition: all 0.3s ease;
							box-shadow: 0 3px 6px rgba(0,0,0,0.16);
							position: relative;
							overflow: hidden;
							}

							#drawBtn:hover:not(:disabled) {
							transform: translateY(-2px);
							box-shadow: 0 6px 12px rgba(0,0,0,0.2);
							background: linear-gradient(to bottom, #66BB6A, #388E3C);
							}

							#drawBtn:active:not(:disabled) {
							transform: translateY(1px);
							box-shadow: 0 2px 4px rgba(0,0,0,0.2);
							}

							#drawBtn:disabled {
							opacity: 0.5;
							cursor: not-allowed;
							background: linear-gradient(to bottom, #A5D6A7, #81C784);
							}

							/* 按钮波纹效果 */
							#drawBtn::after {
							content: '';
							position: absolute;
							top: 50%;
							left: 50%;
							width: 0;
							height: 0;
							background: rgba(255, 255, 255, 0.3);
							border-radius: 50%;
							transform: translate(-50%, -50%);
							opacity: 0;
							}

							#drawBtn:active:not(:disabled)::after {
							animation: ripple 0.6s linear;
							}

							@keyframes ripple {
							0% {
							width: 0;
							height: 0;
							opacity: 1;
							}
							100% {
							width: 300px;
							height: 300px;
							opacity: 0;
							}
							}

							/* 阶段过渡动画 */
							.phase-transition {
							animation: phaseTransition 1s ease-in-out;
							}

							@keyframes phaseTransition {
							0% {
							transform: scale(1);
							box-shadow: 0 0 0 rgba(76, 175, 80, 0);
							}
							50% {
							transform: scale(1.1);
							box-shadow: 0 0 20px rgba(76, 175, 80, 0.7);
							}
							100% {
							transform: scale(1);
							box-shadow: 0 0 0 rgba(76, 175, 80, 0);
							}
							}

							/* 按钮图标 */
							#drawBtn::before {
							content: '🃏';
							margin-right: 8px;
							font-size: 18px;
							}

							/* 按钮状态提示 */
							#drawBtn.active-phase {
							animation: pulse 1.5s infinite;
							border: 2px solid #FFEB3B;
							}

							@keyframes pulse {
							0% {
							box-shadow: 0 0 0 0 rgba(255, 235, 59, 0.7);
							}
							70% {
							box-shadow: 0 0 0 10px rgba(255, 235, 59, 0);
							}
							100% {
							box-shadow: 0 0 0 0 rgba(255, 235, 59, 0);
							}
							}</code>
					</div>
				</span>
			</div>

			<div class="key-points">
				<h3>关键技术点</h3>
				<ul>
					<li>阶段验证机制确保正确的游戏流程</li>
					<li>按钮状态管理（正常/禁用/激活状态）</li>
				</ul>
			</div>
		</div>

		<!-- 3. 卡牌使用机制 -->
		<div class="function-item">
			<div class="function-name">
				useCard(card, index)
				<div class="function-tooltip">
					<strong>useCard(card, index)</strong> - 使用卡牌
					<code>function useCard(card, index) {
						// 检查是否在出牌阶段
						if (phase !== 'play') {
						log(`当前是${getPhaseName(phase)}阶段，不能出牌`);
						return;
						}

						// 检查卡牌是否可用
						if (card.disabled) {
						log(`${card.name} 已被禁用，无法使用`);
						return;
						}

						log(`使用卡牌: ${card.name} (${card.suit}${card.point})`);

						// 根据卡牌类型执行不同效果
						switch (card.name) {
						case '杀':
						handleKillCard(card);
						break;
						case '闪':
						handleDodgeCard(card);
						break;
						case '桃':
						handlePeachCard(card);
						break;
						case '酒':
						handleWineCard(card);
						break;
						case '诸葛连弩':
						handleZhugeLianNu(card);
						break;
						// 其他卡牌类型...
						default:
						handleGenericCard(card);
						}

						// 从手牌中移除
						hand.splice(index, 1);

						// 添加到弃牌堆
						discardPile.push(card);

						// 更新UI
						updateHandDisplay();
						updateDiscardDisplay();

						// 添加使用动画
						animateCardUse(card);

						// 记录最后使用的卡牌
						lastUsedCard = card;

						// 更新杀次数
						if (card.name === '杀') {
						killCount--;
						updateStatus();
						}

						// 检查游戏结束条件
						checkGameEnd();
						}

						// 处理杀牌
						function handleKillCard(card) {
						if (killCount <= 0 && !hasZhugeLianNu) { log("杀次数已用完，无法使用杀"); return; } log("★ 使用杀，对目标造成1点伤害");
							// 实际游戏逻辑：选择目标并造成伤害 } // 处理闪牌 function handleDodgeCard(card) { log("★ 使用闪，抵消一次杀的攻击"); //
							实际游戏逻辑：抵消攻击 } // 处理桃牌 function handlePeachCard(card) { log("★ 使用桃，回复1点体力"); // 实际游戏逻辑：回复体力
							peachCount--; updateRemaining(); } // 处理酒牌 function handleWineCard(card) { log("★
							使用酒，本回合杀伤害+1"); // 实际游戏逻辑：增加杀伤害 wineCount--; updateRemaining(); } // 处理诸葛连弩 function
							handleZhugeLianNu(card) { log("★ 装备诸葛连弩，杀次数上限+1"); hasZhugeLianNu=true; currentWeapon=card;
							updateStatus(); } // 卡牌使用动画 function animateCardUse(card) { const
							cardElement=document.querySelector(`.card[data-uid="${card.uid}" ]`); if (!cardElement)
							return; // 添加使用动画类 cardElement.classList.add('card-used'); // 创建动画副本 const
							clone=cardElement.cloneNode(true); clone.classList.add('card-use-animation');
							clone.style.position='fixed' ; clone.style.zIndex='1000' ; // 添加到动画容器 const
							animationContainer=document.getElementById('animation-container');
							animationContainer.appendChild(clone); // 获取目标位置（弃牌堆） const
							discardPile=document.getElementById('discard-pile'); const
							targetRect=discardPile.getBoundingClientRect(); // 动画效果 anime({ targets: clone, top:
							targetRect.top + 'px' , left: targetRect.left + 'px' , scale: 0.5, opacity: 0, duration:
							800, easing: 'easeInOutQuad' , complete: ()=> {
							clone.remove();
							}
							});

							// 移除原始元素的动画类
							setTimeout(() => {
							cardElement.classList.remove('card-used');
							}, 300);
							}</code>
				</div>
			</div>
			<div class="function-description">
				处理卡牌使用逻辑，包括杀、闪、桃等基本牌和锦囊牌的效果。
			</div>

			<div class="css-section">
				<span class="css-name">
					配套CSS
					<div class="css-tooltip">
						<strong>卡牌使用状态CSS</strong>
						<code>/* 卡牌使用状态 */
							.card-used {
							transform: scale(0.9);
							opacity: 0.7;
							filter: grayscale(80%);
							transition: all 0.3s ease;
							}

							/* 卡牌使用动画 */
							.card-use-animation {
							animation: cardUse 0.8s ease-in-out forwards;
							box-shadow: 0 0 20px rgba(255, 215, 0, 0.7);
							z-index: 1000;
							}

							@keyframes cardUse {
							0% {
							transform: scale(1);
							opacity: 1;
							filter: none;
							}
							50% {
							transform: scale(1.2) rotate(10deg);
							box-shadow: 0 0 30px rgba(255, 87, 34, 0.8);
							filter: brightness(1.5);
							}
							100% {
							transform: scale(0.5) rotate(20deg);
							opacity: 0;
							}
							}

							/* 不同类型卡牌的特殊效果 */
							.card[data-card-type="kill"] {
							border: 2px solid #f44336;
							}

							.card[data-card-type="dodge"] {
							border: 2px solid #2196F3;
							}

							.card[data-card-type="peach"] {
							border: 2px solid #4CAF50;
							}

							.card[data-card-type="wine"] {
							border: 2px solid #FF9800;
							}

							.card[data-card-type="weapon"] {
							border: 2px solid #9C27B0;
							}

							/* 卡牌禁用状态 */
							.card.disabled {
							opacity: 0.5;
							filter: grayscale(100%);
							cursor: not-allowed;
							}

							/* 卡牌悬停效果 */
							.card:not(.disabled):hover {
							transform: translateY(-5px);
							box-shadow: 0 8px 15px rgba(0, 0, 0, 0.2);
							z-index: 10;
							}

							/* 特殊卡牌悬停效果 */
							.card[data-card-type="kill"]:hover {
							box-shadow: 0 8px 15px rgba(244, 67, 54, 0.3);
							}

							.card[data-card-type="dodge"]:hover {
							box-shadow: 0 8px 15px rgba(33, 150, 243, 0.3);
							}

							/* 卡牌激活效果 */
							.card.active {
							animation: cardPulse 1.5s infinite;
							border: 2px solid #FFEB3B;
							}

							@keyframes cardPulse {
							0% {
							box-shadow: 0 0 0 0 rgba(255, 235, 59, 0.7);
							}
							70% {
							box-shadow: 0 0 0 10px rgba(255, 235, 59, 0);
							}
							100% {
							box-shadow: 0 0 0 0 rgba(255, 235, 59, 0);
							}
							}</code>
					</div>
				</span>
			</div>

			<div class="key-points">
				<h3>关键技术点</h3>
				<ul>
					<li>多类型卡牌处理机制（杀、闪、桃、酒、武器等）</li>
					<li>使用CSS变量实现卡牌类型差异化样式</li>
					<li>游戏阶段验证确保正确的出牌时机</li>
					<li>卡牌状态管理（正常/禁用/激活状态）</li>
					<li>卡牌使用后的游戏状态更新</li>
				</ul>
			</div>
		</div>

		<!-- 辅助功能系统 -->
		<div class="function-category">二、辅助功能系统</div>

		<!-- 1. 记牌器功能 -->
		<div class="function-item">
			<div class="function-name">
				updateRemainingCounts()
				<div class="function-tooltip">
					<strong>updateRemainingCounts()</strong> - 更新记牌器
					<code>function updateRemainingCounts() {
						// 重置计数器
						const counts = {
						'杀': 0,
						'闪': 0,
						'桃': 0,
						'酒': 0,
						'诸葛连弩': 0,
						'万箭齐发': 0,
						'南蛮入侵': 0,
						'顺手牵羊': 0,
						'过河拆桥': 0
						};

						// 统计牌堆中各类卡牌数量
						deck.forEach(card => {
						if (counts.hasOwnProperty(card.name)) {
						counts[card.name]++;
						}
						});

						// 更新UI显示
						const container = document.getElementById('remaining-counts');
						container.innerHTML = '';

						// 按类别分组显示
						const categories = {
						'基本牌': ['杀', '闪', '桃', '酒'],
						'装备牌': ['诸葛连弩'],
						'锦囊牌': ['万箭齐发', '南蛮入侵', '顺手牵羊', '过河拆桥']
						};

						// 创建类别分组
						for (const [category, cards] of Object.entries(categories)) {
						const categoryDiv = document.createElement('div');
						categoryDiv.className = 'count-category';

						const header = document.createElement('h3');
						header.textContent = category;
						categoryDiv.appendChild(header);

						const cardList = document.createElement('div');
						cardList.className = 'count-list';

						cards.forEach(cardName => {
						const countItem = document.createElement('div');
						countItem.className = 'count-item';

						const nameSpan = document.createElement('span');
						nameSpan.className = 'card-name';
						nameSpan.textContent = cardName;

						const countSpan = document.createElement('span');
						countSpan.className = 'card-count';
						countSpan.textContent = counts[cardName];

						// 添加特殊样式
						if (counts[cardName] === 0) {
						countSpan.classList.add('zero-count');
						}

						countItem.appendChild(nameSpan);
						countItem.appendChild(countSpan);
						cardList.appendChild(countItem);
						});

						categoryDiv.appendChild(cardList);
						container.appendChild(categoryDiv);
						}

						// 添加折叠/展开功能
						const toggleBtn = document.createElement('button');
						toggleBtn.id = 'toggleCounts';
						toggleBtn.textContent = '收起记牌器';
						toggleBtn.addEventListener('click', () => {
						container.classList.toggle('collapsed');
						toggleBtn.textContent = container.classList.contains('collapsed') ?
						'展开记牌器' : '收起记牌器';
						});

						container.parentNode.insertBefore(toggleBtn, container);

						log("记牌器已更新");
						}</code>
				</div>
			</div>
			<div class="function-description">
				统计并显示各类卡牌的剩余数量，按类别分组展示。
			</div>

			<div class="css-section">
				<span class="css-name">
					配套CSS
					<div class="css-tooltip">
						<strong>记牌器CSS</strong>
						<code>/* 记牌器容器 */
							#remaining-counts {
							background: #fffde7;
							border: 2px solid #ffd54f;
							border-radius: 8px;
							padding: 15px;
							margin: 15px 0;
							transition: all 0.3s ease;
							overflow: hidden;
							}

							/* 折叠状态 */
							#remaining-counts.collapsed {
							max-height: 0;
							padding: 0;
							border: none;
							opacity: 0;
							}

							/* 类别标题 */
							.count-category h3 {
							color: #5d4037;
							margin: 10px 0 5px;
							padding-bottom: 5px;
							border-bottom: 1px dashed #ffd54f;
							font-size: 16px;
							}

							/* 卡片列表 */
							.count-list {
							display: flex;
							flex-wrap: wrap;
							gap: 10px;
							margin-bottom: 15px;
							}

							/* 单张卡片计数 */
							.count-item {
							display: flex;
							align-items: center;
							background: #fff8e1;
							border: 1px solid #ffd54f;
							border-radius: 4px;
							padding: 6px 12px;
							min-width: 100px;
							transition: all 0.2s ease;
							}

							.count-item:hover {
							transform: translateY(-2px);
							box-shadow: 0 3px 6px rgba(0,0,0,0.1);
							background: #ffecb3;
							}

							/* 卡片名称 */
							.card-name {
							flex: 1;
							font-weight: bold;
							color: #5d4037;
							}

							/* 卡片数量 */
							.card-count {
							background: #ffd54f;
							color: #5d4037;
							font-weight: bold;
							width: 30px;
							height: 30px;
							border-radius: 50%;
							display: flex;
							align-items: center;
							justify-content: center;
							margin-left: 8px;
							transition: all 0.3s ease;
							}

							/* 零张特殊样式 */
							.card-count.zero-count {
							background: #ffcdd2;
							color: #c62828;
							animation: pulseWarning 1.5s infinite;
							}

							@keyframes pulseWarning {
							0% {
							box-shadow: 0 0 0 0 rgba(198, 40, 40, 0.4);
							}
							70% {
							box-shadow: 0 0 0 8px rgba(198, 40, 40, 0);
							}
							100% {
							box-shadow: 0 0 0 0 rgba(198, 40, 40, 0);
							}
							}

							/* 折叠按钮 */
							#toggleCounts {
							background: #ffd54f;
							color: #5d4037;
							border: none;
							border-radius: 4px;
							padding: 6px 12px;
							cursor: pointer;
							font-weight: bold;
							transition: all 0.2s ease;
							margin-bottom: 10px;
							}

							#toggleCounts:hover {
							background: #ffc107;
							transform: translateY(-2px);
							box-shadow: 0 3px 6px rgba(0,0,0,0.1);
							}

							#toggleCounts:active {
							transform: translateY(0);
							}

							/* 响应式布局 */
							@media (max-width: 768px) {
							.count-list {
							gap: 8px;
							}

							.count-item {
							min-width: 85px;
							padding: 5px 8px;
							font-size: 14px;
							}

							.card-count {
							width: 25px;
							height: 25px;
							font-size: 14px;
							}
							}</code>
					</div>
				</span>
			</div>

			<div class="key-points">
				<h3>关键技术点</h3>
				<ul>
					<li>动态统计牌堆中各类卡牌数量</li>
					<li>按类别分组展示（基本牌、装备牌、锦囊牌）</li>
					<li>折叠/展开功能节省界面空间</li>
					<li>悬停效果增强交互体验</li>
					<li>响应式设计适应不同屏幕尺寸</li>
				</ul>
			</div>
		</div>

		<!-- 2. 操作日志系统 -->
		<div class="function-item">
			<div class="function-name">
				log(message)
				<div class="function-tooltip">
					<strong>log(message)</strong> - 记录操作日志
					<code>function log(message, type = 'info') {
						const logContainer = document.getElementById('log');
						const now = new Date();

						// 格式化时间 HH:mm:ss
						const timeStr = now.toTimeString().substring(0, 8);

						// 创建日志条目
						const logEntry = document.createElement('div');
						logEntry.className = `log-entry log-${type}`;

						// 添加时间戳
						const timestamp = document.createElement('span');
						timestamp.className = 'log-timestamp';
						timestamp.textContent = `[${timeStr}] `;
						logEntry.appendChild(timestamp);

						// 添加消息内容
						const content = document.createElement('span');
						content.className = 'log-content';
						content.textContent = message;
						logEntry.appendChild(content);

						// 添加到日志容器
						logContainer.appendChild(logEntry);

						// 自动滚动到底部
						logContainer.scrollTop = logContainer.scrollHeight;

						// 添加动画效果
						logEntry.style.opacity = '0';
						setTimeout(() => {
						logEntry.style.transition = 'opacity 0.3s ease';
						logEntry.style.opacity = '1';
						}, 10);

						// 特殊类型日志的额外处理
						if (type === 'warning' || type === 'error') {
						logEntry.classList.add('log-highlight');
						animateLogHighlight(logEntry);
						}
						}

						// 日志高亮动画
						function animateLogHighlight(element) {
						element.animate([
						{ backgroundColor: 'transparent' },
						{ backgroundColor: '#fff9c4', offset: 0.5 },
						{ backgroundColor: 'transparent' }
						], {
						duration: 2000,
						iterations: 1
						});
						}</code>
				</div>
			</div>
			<div class="function-description">
				添加带时间戳的操作日志条目到日志容器。
			</div>

			<div class="css-section">
				<span class="css-name">
					配套CSS
					<div class="css-tooltip">
						<strong>日志容器CSS</strong>
						<code>/* 日志容器 */
							#log {
							max-height: 300px;
							overflow-y: auto;
							padding: 10px;
							background: #f5f5f5;
							border: 1px solid #e0e0e0;
							border-radius: 6px;
							font-family: 'Consolas', 'Monaco', monospace;
							font-size: 14px;
							line-height: 1.5;
							margin-top: 15px;
							}

							/* 滚动条样式 */
							#log::-webkit-scrollbar {
							width: 8px;
							}

							#log::-webkit-scrollbar-track {
							background: #f1f1f1;
							border-radius: 4px;
							}

							#log::-webkit-scrollbar-thumb {
							background: #bdbdbd;
							border-radius: 4px;
							}

							#log::-webkit-scrollbar-thumb:hover {
							background: #9e9e9e;
							}

							/* 日志条目 */
							.log-entry {
							padding: 8px 12px;
							margin-bottom: 6px;
							border-radius: 4px;
							transition: all 0.3s ease;
							animation: fadeIn 0.3s ease;
							}

							@keyframes fadeIn {
							from { opacity: 0; }
							to { opacity: 1; }
							}

							/* 不同日志类型 */
							.log-info {
							background: #e3f2fd;
							border-left: 4px solid #2196F3;
							}

							.log-warning {
							background: #fff8e1;
							border-left: 4px solid #FFC107;
							}

							.log-error {
							background: #ffebee;
							border-left: 4px solid #F44336;
							}

							/* 时间戳样式 */
							.log-timestamp {
							color: #616161;
							font-weight: bold;
							margin-right: 8px;
							}

							/* 日志内容 */
							.log-content {
							color: #212121;
							}

							/* 高亮日志 */
							.log-highlight {
							animation: highlightPulse 2s ease-in-out;
							}

							@keyframes highlightPulse {
							0% {
							box-shadow: 0 0 0 0 rgba(255, 193, 7, 0.7);
							}
							50% {
							box-shadow: 0 0 0 8px rgba(255, 193, 7, 0);
							}
							100% {
							box-shadow: 0 0 0 0 rgba(255, 193, 7, 0);
							}
							}

							/* 日志分隔线 */
							.log-entry:not(:last-child) {
							border-bottom: 1px dashed #e0e0e0;
							}

							/* 响应式设计 */
							@media (max-width: 768px) {
							#log {
							max-height: 200px;
							font-size: 13px;
							}

							.log-entry {
							padding: 6px 8px;
							}

							.log-timestamp {
							display: block;
							margin-bottom: 4px;
							}
							}</code>
					</div>
				</span>
			</div>

			<div class="key-points">
				<h3>关键技术点</h3>
				<ul>
					<li>带时间戳的日志记录（HH:mm:ss格式）</li>
					<li>多级日志类型支持（信息/警告/错误）</li>
					<li>自动滚动到底部确保最新日志可见</li>
					<li>警告和错误日志高亮脉冲效果</li>
					<li>响应式设计适配移动设备</li>
					<li>自定义滚动条提升视觉体验</li>
				</ul>
			</div>
		</div>


		<!-- 3. 脚气卡功能 -->
		<div class="function-item">
			<div class="function-name">
				handleReshuffle()
				<div class="function-tooltip">
					<strong>handleReshuffle()</strong> - 脚气卡功能
					<code>function handleReshuffle() {
						// 检查手牌数量
						if (hand.length < 4) { log("手牌不足4张，无法使用脚气卡"); return; } log("使用脚气卡..."); // 添加动画效果 const
							handArea=document.getElementById('hand'); handArea.classList.add('reshuffling'); // 获取最后4张手牌
							const cardsToReshuffle=hand.slice(-4); // 创建回收动画 animateReshuffle(cardsToReshuffle); //
							延迟执行实际逻辑 setTimeout(()=> {
							// 从手牌中移除最后4张
							hand.splice(-4, 4);

							// 添加到弃牌堆
							discardPile.push(...cardsToReshuffle);

							// 重新洗牌
							shuffleDeck();

							// 抽取4张新牌
							drawCards(4);

							// 更新显示
							updateHandDisplay();
							updateDiscardDisplay();

							// 移除动画类
							handArea.classList.remove('reshuffling');

							log("脚气卡使用完成：回收4张牌，重新洗牌并抽取4张新牌");
							}, 1500);
							}

							// 脚气卡动画效果
							function animateReshuffle(cards) {
							const animationContainer = document.getElementById('animation-container');

							cards.forEach((card, index) => {
							// 找到对应的卡牌元素
							const cardElement = document.querySelector(`.card[data-uid="${card.uid}"]`);
							if (!cardElement) return;

							// 创建动画副本
							const clone = cardElement.cloneNode(true);
							clone.classList.add('reshuffle-animation');
							clone.style.position = 'fixed';
							clone.style.zIndex = '1000';

							// 设置初始位置
							const rect = cardElement.getBoundingClientRect();
							clone.style.left = `${rect.left}px`;
							clone.style.top = `${rect.top}px`;

							animationContainer.appendChild(clone);

							// 动画效果
							anime({
							targets: clone,
							translateX: [0, -100 + index * 50],
							translateY: [0, -200],
							rotate: [0, 360],
							scale: [1, 1.5],
							opacity: [1, 0],
							duration: 1200,
							delay: index * 100,
							easing: 'easeInOutQuad',
							complete: () => {
							clone.remove();
							}
							});
							});
							}</code>
				</div>
			</div>
			<div class="function-description">
				使用脚气卡功能，回收最后4张手牌，重新洗牌并抽取新牌。
			</div>

			<div class="css-section">
				<span class="css-name">
					配套CSS
					<div class="css-tooltip">
						<strong>脚气卡按钮CSS</strong>
						<code>/* 脚气卡按钮 */
							#reshuffleBtn {
							background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%);
							color: white;
							border: none;
							border-radius: 30px;
							padding: 12px 24px;
							font-size: 16px;
							font-weight: bold;
							cursor: pointer;
							transition: all 0.3s ease;
							box-shadow: 0 6px 12px rgba(106, 17, 203, 0.3);
							position: relative;
							overflow: hidden;
							text-transform: uppercase;
							letter-spacing: 1px;
							}

							#reshuffleBtn:hover:not(:disabled) {
							transform: translateY(-3px);
							box-shadow: 0 8px 15px rgba(106, 17, 203, 0.4);
							background: linear-gradient(135deg, #7a21db 0%, #3585ff 100%);
							}

							#reshuffleBtn:active:not(:disabled) {
							transform: translateY(1px);
							box-shadow: 0 3px 6px rgba(106, 17, 203, 0.3);
							}

							#reshuffleBtn:disabled {
							opacity: 0.6;
							cursor: not-allowed;
							}

							/* 按钮发光效果 */
							#reshuffleBtn::after {
							content: '';
							position: absolute;
							top: -50%;
							left: -50%;
							width: 200%;
							height: 200%;
							background: rgba(255, 255, 255, 0.1);
							transform: rotate(45deg);
							transition: all 0.6s ease;
							}

							#reshuffleBtn:hover:not(:disabled)::after {
							top: -10%;
							left: -10%;
							}

							/* 按钮图标 */
							#reshuffleBtn::before {
							content: '🔄';
							margin-right: 8px;
							font-size: 18px;
							}

							/* 脚气卡动画 */
							.reshuffle-animation {
							animation: reshuffleFloat 1.2s ease-in-out forwards;
							box-shadow: 0 0 20px rgba(106, 17, 203, 0.7);
							z-index: 1000;
							}

							@keyframes reshuffleFloat {
							0% {
							transform: translate(0, 0) rotate(0deg) scale(1);
							opacity: 1;
							}
							50% {
							transform: translate(0, -100px) rotate(180deg) scale(1.2);
							box-shadow: 0 0 30px rgba(106, 17, 203, 0.9);
							}
							100% {
							transform: translate(0, -200px) rotate(360deg) scale(0.5);
							opacity: 0;
							}
							}

							/* 手牌区域动画 */
							#hand.reshuffling {
							position: relative;
							overflow: visible;
							}

							#hand.reshuffling::before {
							content: '';
							position: absolute;
							top: 0;
							left: 0;
							right: 0;
							bottom: 0;
							background: rgba(106, 17, 203, 0.1);
							border-radius: 8px;
							animation: reshuffleGlow 1.5s infinite alternate;
							z-index: -1;
							}

							@keyframes reshuffleGlow {
							from {
							box-shadow: 0 0 10px rgba(106, 17, 203, 0.3);
							}
							to {
							box-shadow: 0 0 30px rgba(106, 17, 203, 0.7);
							}
							}

							/* 按钮状态提示 */
							#reshuffleBtn.active-reshuffle {
							animation: reshufflePulse 1.5s infinite;
							}

							@keyframes reshufflePulse {
							0% {
							box-shadow: 0 0 0 0 rgba(106, 17, 203, 0.7);
							}
							70% {
							box-shadow: 0 0 0 15px rgba(106, 17, 203, 0);
							}
							100% {
							box-shadow: 0 0 0 0 rgba(106, 17, 203, 0);
							}
							}</code>
					</div>
				</span>
			</div>

			<div class="key-points">
				<h3>关键技术点</h3>
				<ul>
					<li>手牌数量验证确保功能可用性</li>
					<li>使用anime.js实现流畅的卡牌回收动画</li>
					<li>渐变背景和阴影创造深度效果</li>
					<li>按钮悬停发光效果增强交互体验</li>
					<li>脉冲动画提示功能可用状态</li>
					<li>手牌区域视觉反馈（发光效果）</li>
					<li>禁用状态处理防止无效操作</li>
				</ul>
			</div>
		</div>

		<!-- 安全与验证系统 -->
		<div class="function-category">三、安全与验证系统</div>

		<!-- 1. 加密验证功能 -->
		<div class="function-item">
			<div class="function-name">
				generateDeckMD5()
				<div class="function-tooltip">
					<strong>generateDeckMD5()</strong> - 生成牌堆MD5
					<code>function generateDeckMD5() {
						// 创建牌堆数据的字符串表示
						const deckData = deck.map(card =>
						`${card.name}|${card.suit}|${card.point}|${card.uid}`
						).join(';');

						// 使用CryptoJS计算MD5哈希
						const hash = CryptoJS.MD5(deckData).toString();

						// 存储哈希值
						deckMD5 = hash;

						// 更新显示
						updateMD5Display();

						// 添加安全日志
						securityLog.push({
						timestamp: new Date().toISOString(),
						action: 'generate_deck_md5',
						hash: hash,
						deckSize: deck.length
						});

						log(`牌堆MD5已更新: ${hash.substring(0, 8)}...`);

						return hash;
						}

						// 更新MD5显示
						function updateMD5Display() {
						const md5Element = document.getElementById('md5Value');
						if (!md5Element) return;

						// 显示前8位和后8位
						const displayHash = deckMD5 ?
						`${deckMD5.substring(0, 8)}...${deckMD5.substring(24)}` :
						'未生成';

						md5Element.textContent = displayHash;

						// 添加复制按钮功能
						md5Element.onclick = function() {
						navigator.clipboard.writeText(deckMD5)
						.then(() => {
						const originalText = this.textContent;
						this.textContent = '已复制!';
						this.classList.add('copied');

						setTimeout(() => {
						this.textContent = originalText;
						this.classList.remove('copied');
						}, 2000);
						})
						.catch(err => {
						console.error('复制失败:', err);
						});
						};
						}</code>
				</div>
			</div>
			<div class="function-description">
				生成牌堆的MD5标识符，用于安全验证。
			</div>

			<div class="css-section">
				<span class="css-name">
					配套CSS
					<div class="css-tooltip">
						<strong>加密面板CSS</strong>
						<code>/* MD5验证面板 */
							.md5-panel {
							background: #e8f5e9;
							border: 1px solid #4CAF50;
							border-radius: 8px;
							padding: 15px;
							margin: 15px 0;
							position: relative;
							overflow: hidden;
							}

							.md5-panel::before {
							content: '安全验证';
							position: absolute;
							top: -10px;
							left: 15px;
							background: #4CAF50;
							color: white;
							padding: 2px 10px;
							border-radius: 4px;
							font-size: 12px;
							font-weight: bold;
							}

							/* MD5值显示 */
							#md5Value {
							display: inline-block;
							background: #2d2d2d;
							color: #4CAF50;
							font-family: 'Consolas', 'Monaco', monospace;
							padding: 8px 15px;
							border-radius: 4px;
							margin: 10px 0;
							cursor: pointer;
							transition: all 0.3s ease;
							border: 1px solid #4CAF50;
							box-shadow: 0 2px 5px rgba(0,0,0,0.1);
							min-width: 200px;
							text-align: center;
							overflow: hidden;
							text-overflow: ellipsis;
							}

							#md5Value:hover {
							background: #3d3d3d;
							box-shadow: 0 4px 8px rgba(0,0,0,0.15);
							}

							#md5Value.copied {
							background: #388E3C;
							color: white;
							animation: pulseSuccess 1s;
							}

							@keyframes pulseSuccess {
							0% {
							box-shadow: 0 0 0 0 rgba(56, 142, 60, 0.7);
							}
							70% {
							box-shadow: 0 0 0 10px rgba(56, 142, 60, 0);
							}
							100% {
							box-shadow: 0 0 0 0 rgba(56, 142, 60, 0);
							}
							}

							/* 验证结果样式 */
							#verifyResult {
							padding: 8px 12px;
							border-radius: 4px;
							font-weight: bold;
							margin-top: 10px;
							display: inline-block;
							}

							.verify-success {
							background: #E8F5E9;
							color: #2E7D32;
							border: 1px solid #4CAF50;
							}

							.verify-failure {
							background: #FFEBEE;
							color: #C62828;
							border: 1px solid #F44336;
							}

							/* 验证按钮 */
							#verifyBtn {
							background: #4CAF50;
							color: white;
							border: none;
							padding: 8px 16px;
							border-radius: 4px;
							cursor: pointer;
							transition: all 0.3s ease;
							margin-top: 10px;
							font-weight: bold;
							}

							#verifyBtn:hover {
							background: #388E3C;
							transform: translateY(-2px);
							box-shadow: 0 4px 8px rgba(0,0,0,0.2);
							}

							#verifyBtn:active {
							transform: translateY(0);
							}

							/* 安全图标 */
							.md5-icon {
							display: inline-block;
							margin-right: 8px;
							font-size: 18px;
							}

							/* 响应式设计 */
							@media (max-width: 768px) {
							.md5-panel {
							padding: 12px;
							}

							#md5Value {
							min-width: 180px;
							font-size: 14px;
							padding: 6px 12px;
							}
							}</code>
					</div>
				</span>
			</div>

			<div class="key-points">
				<h3>关键技术点</h3>
				<ul>
					<li>使用CryptoJS库实现MD5哈希计算</li>
					<li>牌堆数据序列化确保哈希一致性</li>
					<li>安全日志记录所有哈希生成操作</li>
					<li>复制功能增强用户体验</li>
					<li>视觉反馈显示复制成功状态</li>
					<li>响应式设计适配不同屏幕尺寸</li>
					<li>悬停效果提升交互体验</li>
				</ul>
			</div>
		</div>

		<div class="function-item">
			<div class="function-name">
				generateDeckAES()
				<div class="function-tooltip">
					<strong>generateDeckAES()</strong> - 生成牌堆AES加密
					<code>function generateDeckAES() {
						// 创建牌堆数据的JSON字符串
						const deckData = JSON.stringify({
						timestamp: new Date().toISOString(),
						deck: deck.map(card => ({
						name: card.name,
						suit: card.suit,
						point: card.point,
						uid: card.uid
						}))
						});

						// 使用CryptoJS进行AES-256加密
						const encrypted = CryptoJS.AES.encrypt(
						deckData,
						AES_SECRET_KEY,
						{ mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }
						).toString();

						// 存储加密结果
						deckAES = encrypted;

						// 更新显示
						updateAESDisplay();

						// 添加安全日志
						securityLog.push({
						timestamp: new Date().toISOString(),
						action: 'generate_deck_aes',
						encrypted: encrypted.substring(0, 50) + '...' // 只存储部分
						});

						log(`牌堆AES加密完成: ${encrypted.substring(0, 15)}...`);

						return encrypted;
						}

						// 更新AES显示
						function updateAESDisplay() {
						const aesElement = document.getElementById('aesValue');
						if (!aesElement) return;

						// 显示前15位和后15位
						const displayText = deckAES ?
						`${deckAES.substring(0, 15)}...${deckAES.substring(deckAES.length - 15)}` :
						'未生成';

						aesElement.textContent = displayText;

						// 添加复制功能
						aesElement.onclick = function() {
						navigator.clipboard.writeText(deckAES)
						.then(() => {
						const originalText = this.textContent;
						this.textContent = '已复制!';
						this.classList.add('copied');

						setTimeout(() => {
						this.textContent = originalText;
						this.classList.remove('copied');
						}, 2000);
						})
						.catch(err => {
						console.error('复制失败:', err);
						});
						};

						// 添加解密按钮功能
						const decryptBtn = document.getElementById('decryptBtn');
						if (decryptBtn) {
						decryptBtn.disabled = !deckAES;
						}
						}

						// 解密牌堆数据
						function decryptDeckData(encryptedData) {
						try {
						const decrypted = CryptoJS.AES.decrypt(
						encryptedData,
						AES_SECRET_KEY,
						{ mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }
						).toString(CryptoJS.enc.Utf8);

						if (!decrypted) {
						throw new Error('解密失败或密钥错误');
						}

						return JSON.parse(decrypted);
						} catch (error) {
						log(`解密错误: ${error.message}`, 'error');
						return null;
						}
						}</code>
				</div>
			</div>
			<div class="function-description">
				使用AES-256算法加密牌堆数据，生成安全编码。
			</div>

			<div class="css-section">
				<span class="css-name">
					配套CSS
					<div class="css-tooltip">
						<strong>AES显示CSS</strong>
						<code>/* AES加密面板 */
							.aes-panel {
							background: #e3f2fd;
							border: 1px solid #2196F3;
							border-radius: 8px;
							padding: 15px;
							margin: 15px 0;
							position: relative;
							overflow: hidden;
							}

							.aes-panel::before {
							content: '高级加密';
							position: absolute;
							top: -10px;
							left: 15px;
							background: #2196F3;
							color: white;
							padding: 2px 10px;
							border-radius: 4px;
							font-size: 12px;
							font-weight: bold;
							}

							/* AES值显示 */
							#aesValue {
							display: inline-block;
							background: #2d2d2d;
							color: #2196F3;
							font-family: 'Consolas', 'Monaco', monospace;
							padding: 8px 15px;
							border-radius: 4px;
							margin: 10px 0;
							cursor: pointer;
							transition: all 0.3s ease;
							border: 1px solid #2196F3;
							box-shadow: 0 2px 5px rgba(0,0,0,0.1);
							min-width: 300px;
							text-align: center;
							overflow: hidden;
							text-overflow: ellipsis;
							font-size: 14px;
							}

							#aesValue:hover {
							background: #3d3d3d;
							box-shadow: 0 4px 8px rgba(0,0,0,0.15);
							}

							#aesValue.copied {
							background: #1976D2;
							color: white;
							animation: pulseSuccessBlue 1s;
							}

							@keyframes pulseSuccessBlue {
							0% {
							box-shadow: 0 0 0 0 rgba(25, 118, 210, 0.7);
							}
							70% {
							box-shadow: 0 0 0 10px rgba(25, 118, 210, 0);
							}
							100% {
							box-shadow: 0 0 0 0 rgba(25, 118, 210, 0);
							}
							}

							/* 解密按钮 */
							#decryptBtn {
							background: #2196F3;
							color: white;
							border: none;
							padding: 8px 16px;
							border-radius: 4px;
							cursor: pointer;
							transition: all 0.3s ease;
							margin-top: 10px;
							font-weight: bold;
							display: inline-flex;
							align-items: center;
							}

							#decryptBtn:disabled {
							opacity: 0.5;
							cursor: not-allowed;
							}

							#decryptBtn:not(:disabled):hover {
							background: #1976D2;
							transform: translateY(-2px);
							box-shadow: 0 4px 8px rgba(0,0,0,0.2);
							}

							#decryptBtn:not(:disabled):active {
							transform: translateY(0);
							}

							/* 按钮图标 */
							#decryptBtn::before {
							content: '🔓';
							margin-right: 8px;
							font-size: 16px;
							}

							/* 解密结果区域 */
							#decryptResult {
							margin-top: 15px;
							padding: 12px;
							background: #f5f5f5;
							border-radius: 6px;
							border: 1px dashed #bdbdbd;
							font-family: 'Consolas', 'Monaco', monospace;
							font-size: 13px;
							max-height: 200px;
							overflow-y: auto;
							white-space: pre-wrap;
							}

							/* 安全锁图标 */
							.aes-icon {
							display: inline-block;
							margin-right: 8px;
							font-size: 18px;
							}

							/* 响应式设计 */
							@media (max-width: 768px) {
							.aes-panel {
							padding: 12px;
							}

							#aesValue {
							min-width: 250px;
							font-size: 12px;
							padding: 6px 12px;
							}

							#decryptResult {
							font-size: 12px;
							}
							}</code>
					</div>
				</span>
			</div>

			<div class="key-points">
				<h3>关键技术点</h3>
				<ul>
					<li>AES-256加密算法保障数据安全</li>
					<li>CBC模式+Pkcs7填充提供高级安全性</li>
					<li>加密数据包含时间戳确保时效性</li>
					<li>完整的加密/解密功能实现</li>
					<li>安全日志记录所有加密操作</li>
					<li>复制功能增强用户体验</li>
					<li>解密功能支持数据验证</li>
					<li>响应式设计适配不同屏幕尺寸</li>
				</ul>
			</div>
		</div>

		<!-- 2. 安全日志功能 -->
		<div class="function-item">
			<div class="function-name">
				generateSecurityLog()
				<div class="function-tooltip">
					<strong>generateSecurityLog()</strong> - 生成安全日志
					<code>function generateSecurityLog() {
						// 创建日志数据
						const logData = {
						timestamp: new Date().toISOString(),
						deckMD5: deckMD5,
						deckAES: deckAES,
						deckSize: deck.length,
						handSize: hand.length,
						discardSize: discardPile.length,
						reshuffleUsed: reshuffleUsed,
						securityEvents: securityLog
						};

						// 转换为JSON字符串
						const logString = JSON.stringify(logData, null, 2);

						// 创建Blob对象
						const blob = new Blob([logString], { type: 'application/json' });
						const url = URL.createObjectURL(blob);

						// 创建下载链接
						const downloadLink = document.createElement('a');
						downloadLink.href = url;
						downloadLink.download = `security_log_${new Date().getTime()}.json`;
						downloadLink.textContent = '下载安全日志';
						downloadLink.className = 'security-download';

						// 添加到日志容器
						const logContainer = document.getElementById('securityLog');
						logContainer.innerHTML = '';
						logContainer.appendChild(downloadLink);

						// 添加日志预览
						const preview = document.createElement('pre');
						preview.className = 'log-preview';
						preview.textContent = logString;
						logContainer.appendChild(preview);

						log("安全日志已生成，可下载查看");

						// 添加安全日志记录
						securityLog.push({
						timestamp: new Date().toISOString(),
						action: 'generate_security_log',
						logSize: logString.length
						});

						return logString;
						}

						// 安全日志查看器
						function viewSecurityLog() {
						const logData = generateSecurityLog();
						showModal('安全日志详情', `&lt;pre&gt;${logData}&lt;/pre&gt;`);
						}</code>
				</div>
			</div>
			<div class="function-description">
				生成包含牌堆详细信息的JSON格式日志文件，支持下载和预览。
			</div>

			<div class="css-section">
				<span class="css-name">
					配套CSS
					<div class="css-tooltip">
						<strong>安全日志CSS</strong>
						<code>/* 安全日志容器 */
							#securityLog {
							background: #fff3e0;
							border: 1px solid #ff9800;
							border-radius: 8px;
							padding: 15px;
							margin: 15px 0;
							position: relative;
							overflow: hidden;
							}

							#securityLog::before {
							content: '安全日志';
							position: absolute;
							top: -10px;
							left: 15px;
							background: #ff9800;
							color: white;
							padding: 2px 10px;
							border-radius: 4px;
							font-size: 12px;
							font-weight: bold;
							}

							/* 下载链接 */
							.security-download {
							display: inline-block;
							background: #ff9800;
							color: white;
							padding: 10px 20px;
							border-radius: 4px;
							text-decoration: none;
							font-weight: bold;
							transition: all 0.3s ease;
							margin-bottom: 15px;
							box-shadow: 0 3px 6px rgba(0,0,0,0.1);
							}

							.security-download:hover {
							background: #f57c00;
							transform: translateY(-2px);
							box-shadow: 0 5px 10px rgba(0,0,0,0.15);
							}

							.security-download:active {
							transform: translateY(0);
							}

							/* 日志预览 */
							.log-preview {
							background: #2d2d2d;
							color: #f8f8f2;
							padding: 15px;
							border-radius: 6px;
							font-family: 'Consolas', 'Monaco', monospace;
							font-size: 13px;
							line-height: 1.5;
							max-height: 300px;
							overflow: auto;
							margin-top: 15px;
							border: 1px solid #555;
							}

							/* 日志高亮 */
							.log-preview .timestamp {
							color: #f92672;
							}

							.log-preview .action {
							color: #a6e22e;
							}

							.log-preview .hash {
							color: #66d9ef;
							}

							/* 滚动条样式 */
							.log-preview::-webkit-scrollbar {
							width: 8px;
							}

							.log-preview::-webkit-scrollbar-track {
							background: #3d3d3d;
							border-radius: 4px;
							}

							.log-preview::-webkit-scrollbar-thumb {
							background: #ff9800;
							border-radius: 4px;
							}

							.log-preview::-webkit-scrollbar-thumb:hover {
							background: #ffab40;
							}

							/* 安全日志按钮 */
							#securityLogBtn {
							background: #ff9800;
							color: white;
							border: none;
							padding: 10px 20px;
							border-radius: 4px;
							cursor: pointer;
							transition: all 0.3s ease;
							font-weight: bold;
							display: flex;
							align-items: center;
							margin: 10px 0;
							}

							#securityLogBtn:hover {
							background: #f57c00;
							transform: translateY(-2px);
							box-shadow: 0 5px 10px rgba(0,0,0,0.15);
							}

							#securityLogBtn:active {
							transform: translateY(0);
							}

							/* 按钮图标 */
							#securityLogBtn::before {
							content: '🔒';
							margin-right: 8px;
							font-size: 16px;
							}

							/* 响应式设计 */
							@media (max-width: 768px) {
							#securityLog {
							padding: 12px;
							}

							.log-preview {
							font-size: 12px;
							padding: 10px;
							max-height: 200px;
							}

							.security-download {
							padding: 8px 16px;
							font-size: 14px;
							}
							}</code>
					</div>
				</span>
			</div>

			<div class="key-points">
				<h3>关键技术点</h3>
				<ul>
					<li>JSON格式日志包含完整游戏状态信息</li>
					<li>Blob对象实现前端文件下载功能</li>
					<li>带语法高亮的日志预览功能</li>
					<li>自定义滚动条提升用户体验</li>
					<li>响应式设计适配不同屏幕尺寸</li>
					<li>时间戳记录所有安全操作</li>
					<li>模态框支持详细日志查看</li>
				</ul>
			</div>
		</div>

		<!-- 测试与开发工具 -->
		<div class="function-category">四、测试与开发工具</div>

		<!-- 1. 洗牌测试功能 -->
		<div class="function-item">
			<div class="function-name">
				testShuffleUniformity()
				<div class="function-tooltip">
					<strong>testShuffleUniformity()</strong> - 洗牌均匀性测试
					<code>function testShuffleUniformity() {
						// 创建测试面板
						createTestPanel();

						// 重置测试结果
						testResults = {
						totalTests: 0,
						positionCounts: {},
						cardDistribution: {}
						};

						// 初始化统计数据
						for (let i = 0; i < 160; i++) { testResults.positionCounts[i]=0; } // 设置测试卡牌 const testCard={
							name: "测试卡" , suit: "♠" , point: 7, uid: "TEST_CARD_001" }; // 添加测试卡到牌堆 deck.push(testCard);
							// 开始测试 log("开始洗牌均匀性测试..."); startUniformityTest(); } // 创建测试面板 function createTestPanel() {
							// 检查是否已存在测试面板 if (document.getElementById('testPanel')) return; // 创建测试面板 const
							panel=document.createElement('div'); panel.id='testPanel' ; panel.className='test-panel' ;
							panel.innerHTML=` <h3>洗牌均匀性测试</h3>
							<div class="test-controls">
								<button id="startTest">开始测试</button>
								<button id="stopTest">停止测试</button>
								<input type="number" id="testCount" value="1000" min="100" max="100000">
								<label for="testCount">测试次数</label>
							</div>
							<div class="progress-container">
								<progress id="testProgress" value="0" max="100"></progress>
								<span id="progressText">0%</span>
							</div>
							<div class="results-container">
								<div class="result-chart" id="positionChart"></div>
								<div class="result-stats" id="statResults"></div>
							</div>
							`;

							// 添加到页面
							document.body.appendChild(panel);

							// 绑定事件
							document.getElementById('startTest').addEventListener('click', startUniformityTest);
							document.getElementById('stopTest').addEventListener('click', stopUniformityTest);
							}

							// 开始均匀性测试
							function startUniformityTest() {
							if (isTesting) return;

							const testCount = parseInt(document.getElementById('testCount').value) || 1000;
							isTesting = true;
							testResults.totalTests = testCount;

							// 重置进度
							const progressBar = document.getElementById('testProgress');
							const progressText = document.getElementById('progressText');
							progressBar.value = 0;
							progressText.textContent = '0%';

							// 执行测试
							let completed = 0;
							const testCard = deck.find(card => card.uid === "TEST_CARD_001");

							const testInterval = setInterval(() => {
							if (!isTesting) {
							clearInterval(testInterval);
							return;
							}

							// 洗牌
							shuffleDeck();

							// 查找测试卡位置
							const position = deck.findIndex(card => card.uid === testCard.uid);

							// 更新统计数据
							testResults.positionCounts[position] = (testResults.positionCounts[position] || 0) + 1;

							// 更新进度
							completed++;
							const percent = Math.round((completed / testCount) * 100);
							progressBar.value = percent;
							progressText.textContent = `${percent}%`;

							// 每10次更新一次结果
							if (completed % 10 === 0) {
							updateTestResults();
							}

							// 测试完成
							if (completed >= testCount) {
							clearInterval(testInterval);
							isTesting = false;
							log(`洗牌均匀性测试完成，共测试 ${testCount} 次`);
							updateTestResults(true);
							}
							}, 10);
							}

							// 停止测试
							function stopUniformityTest() {
							isTesting = false;
							log("测试已停止");
							}

							// 更新测试结果
							function updateTestResults(final = false) {
							const positionChart = document.getElementById('positionChart');
							const statResults = document.getElementById('statResults');

							// 清空容器
							positionChart.innerHTML = '';
							statResults.innerHTML = '';

							// 计算统计数据
							const totalTests = testResults.totalTests;
							let minPosition = Infinity;
							let maxPosition = -Infinity;
							let minCount = Infinity;
							let maxCount = -Infinity;

							// 找到最小和最大位置
							for (let i = 0; i < 160; i++) { if (testResults.positionCounts[i]> 0) {
								if (i < minPosition) minPosition=i; if (i> maxPosition) maxPosition = i;
									}
									}

									// 创建图表
									const chartHeight = 200;
									const barWidth = 3;
									const containerWidth = (maxPosition - minPosition + 1) * (barWidth + 1);

									positionChart.style.width = `${containerWidth}px`;

									// 创建条形图
									for (let i = minPosition; i <= maxPosition; i++) { const
										count=testResults.positionCounts[i] || 0; const barHeight=count> 0 ? Math.max(1,
										(count / totalTests) * chartHeight * 10) : 0;

										const bar = document.createElement('div');
										bar.className = 'chart-bar';
										bar.style.height = `${barHeight}px`;
										bar.style.width = `${barWidth}px`;
										bar.style.left = `${(i - minPosition) * (barWidth + 1)}px`;
										bar.style.bottom = '0';

										// 添加悬停提示
										bar.title = `位置 ${i}: ${count} 次 (${((count / totalTests) * 100).toFixed(2)}%)`;

										positionChart.appendChild(bar);

										// 更新最小/最大值
										if (count < minCount) minCount=count; if (count> maxCount) maxCount = count;
											}

											// 添加统计信息
											const expected = totalTests / deck.length;
											const deviation = ((maxCount - minCount) / expected) * 100;

											statResults.innerHTML = `
											<h4>统计结果</h4>
											<p>测试次数: ${totalTests}</p>
											<p>牌堆大小: ${deck.length}</p>
											<p>最小位置: ${minPosition} (${minCount}次)</p>
											<p>最大位置: ${maxPosition} (${maxCount}次)</p>
											<p>期望次数: ${expected.toFixed(2)}</p>
											<p>最大偏差: ${deviation.toFixed(2)}%</p>
											<p>标准差: ${calculateStandardDeviation().toFixed(2)}</p>
											`;

											// 最终结果添加动画
											if (final) {
											positionChart.classList.add('final-results');
											statResults.classList.add('final-results');
											}
											}

											// 计算标准差
											function calculateStandardDeviation() {
											const totalTests = testResults.totalTests;
											const deckSize = deck.length;
											const expected = totalTests / deckSize;

											let sumSquaredDiff = 0;
											for (let i = 0; i < deckSize; i++) { const
												count=testResults.positionCounts[i] || 0; const diff=count - expected;
												sumSquaredDiff +=diff * diff; } return Math.sqrt(sumSquaredDiff /
												deckSize); }</code>
				</div>
			</div>
			<div class="function-description">
				执行洗牌均匀性测试，统计特定卡牌在牌堆中不同位置出现的概率分布。
			</div>

			<div class="css-section">
				<span class="css-name">
					配套CSS
					<div class="css-tooltip">
						<strong>测试面板CSS</strong>
						<code>/* 测试面板 */
							.test-panel {
							position: fixed;
							top: 50%;
							left: 50%;
							transform: translate(-50%, -50%);
							width: 90%;
							max-width: 800px;
							background: white;
							border-radius: 12px;
							box-shadow: 0 10px 30px rgba(0,0,0,0.2);
							padding: 20px;
							z-index: 3000;
							max-height: 90vh;
							overflow-y: auto;
							}

							.test-panel h3 {
							color: #8e0e00;
							text-align: center;
							margin-top: 0;
							padding-bottom: 10px;
							border-bottom: 2px solid #f1c40f;
							}

							/* 测试控制区 */
							.test-controls {
							display: flex;
							justify-content: center;
							gap: 15px;
							margin: 20px 0;
							flex-wrap: wrap;
							align-items: center;
							}

							.test-controls button {
							padding: 10px 20px;
							border: none;
							border-radius: 6px;
							font-weight: bold;
							cursor: pointer;
							transition: all 0.3s ease;
							}

							#startTest {
							background: #4CAF50;
							color: white;
							}

							#stopTest {
							background: #F44336;
							color: white;
							}

							.test-controls button:hover {
							transform: translateY(-2px);
							box-shadow: 0 4px 8px rgba(0,0,0,0.2);
							}

							.test-controls button:active {
							transform: translateY(0);
							}

							.test-controls input {
							width: 100px;
							padding: 8px;
							border: 1px solid #ddd;
							border-radius: 4px;
							text-align: center;
							}

							.test-controls label {
							font-size: 14px;
							color: #666;
							}

							/* 进度条容器 */
							.progress-container {
							position: relative;
							height: 30px;
							margin: 20px 0;
							background: #f5f5f5;
							border-radius: 15px;
							overflow: hidden;
							}

							#testProgress {
							width: 100%;
							height: 100%;
							appearance: none;
							border: none;
							}

							#testProgress::-webkit-progress-bar {
							background: #f5f5f5;
							}

							#testProgress::-webkit-progress-value {
							background: linear-gradient(to right, #4CAF50, #8BC34A);
							transition: width 0.3s ease;
							}

							#progressText {
							position: absolute;
							top: 0;
							left: 0;
							width: 100%;
							height: 100%;
							display: flex;
							align-items: center;
							justify-content: center;
							font-weight: bold;
							color: #333;
							pointer-events: none;
							}

							/* 结果容器 */
							.results-container {
							display: flex;
							gap: 20px;
							margin-top: 20px;
							}

							.result-chart {
							flex: 1;
							height: 220px;
							background: #f9f9f9;
							border: 1px solid #eee;
							border-radius: 6px;
							position: relative;
							overflow: hidden;
							}

							.result-stats {
							width: 300px;
							background: #f5f5f5;
							padding: 15px;
							border-radius: 6px;
							font-size: 14px;
							}

							.result-stats h4 {
							margin-top: 0;
							color: #8e0e00;
							border-bottom: 1px solid #ddd;
							padding-bottom: 5px;
							}

							.result-stats p {
							margin: 8px 0;
							}

							/* 图表条形 */
							.chart-bar {
							position: absolute;
							background: linear-gradient(to top, #4CAF50, #8BC34A);
							transition: height 0.5s ease;
							}

							.chart-bar:hover {
							background: linear-gradient(to top, #f44336, #ff9800);
							z-index: 10;
							}

							/* 最终结果动画 */
							.final-results {
							animation: finalResultPulse 2s ease-in-out;
							}

							@keyframes finalResultPulse {
							0% {
							box-shadow: 0 0 0 0 rgba(76, 175, 80, 0.5);
							}
							50% {
							box-shadow: 0 0 0 15px rgba(76, 175, 80, 0);
							}
							100% {
							box-shadow: 0 0 0 0 rgba(76, 175, 80, 0);
							}
							}

							/* 响应式设计 */
							@media (max-width: 768px) {
							.results-container {
							flex-direction: column;
							}

							.result-stats {
							width: 100%;
							}

							.test-panel {
							width: 95%;
							padding: 15px;
							}
							}</code>
					</div>
				</span>
			</div>

			<div class="key-points">
				<h3>关键技术点</h3>
				<ul>
					<li>动态创建测试面板实现非侵入式测试</li>
					<li>实时进度条显示测试进度</li>
					<li>动态条形图可视化位置分布</li>
					<li>标准差计算评估洗牌均匀性</li>
					<li>十万次洗牌数据</li>
					<li>实时更新测试结果</li>
					<li>响应式设计适配不同屏幕尺寸</li>
				</ul>
			</div>
		</div>

		<!-- 2. 开发者工具 -->
		<div class="function-item">
			<div class="function-name">
				addSpecificCard(cardName)
				<div class="function-tooltip">
					<strong>addSpecificCard(cardName)</strong> - 添加指定卡牌
					<code>function addSpecificCard(cardName) {
						// 检查是否在开发者模式
						if (!isDevMode) {
						log("开发者模式未启用，无法添加指定卡牌");
						return;
						}

						// 在标准牌堆中查找匹配的卡牌
						const cardTemplate = standardDeck.find(c => c.name === cardName);
						if (!cardTemplate) {
						log(`找不到卡牌: ${cardName}`);
						return;
						}

						// 创建新卡牌实例
						const newCard = {
						name: cardTemplate.name,
						suit: cardTemplate.suits[0].match(/^([♠♥♣♦])/)[1],
						point: parseInt(cardTemplate.suits[0].match(/(\d+|[JQKA])$/)[0].replace('J', '11').replace('Q',
						'12').replace('K', '13').replace('A', '1')),
						uid: `DEV_${Date.now()}_${Math.floor(Math.random() * 1000)}`
						};

						// 添加到手牌
						hand.push(newCard);

						// 更新UI
						updateHandDisplay();

						// 添加动画效果
						animateCardAddition(newCard);

						log(`开发者: 已添加 ${cardName} 到手牌`);
						}

						// 卡牌添加动画
						function animateCardAddition(card) {
						const animationContainer = document.getElementById('animation-container');

						// 创建动画元素
						const cardElement = document.createElement('div');
						cardElement.className = 'card dev-card-addition';
						cardElement.textContent = `${card.name} (${card.suit}${card.point})`;
						cardElement.style.position = 'fixed';
						cardElement.style.zIndex = '2000';
						cardElement.style.top = '20px';
						cardElement.style.right = '20px';
						cardElement.style.transform = 'scale(0.8)';
						cardElement.style.opacity = '0';

						animationContainer.appendChild(cardElement);

						// 获取目标位置（手牌区域）
						const handArea = document.getElementById('hand');
						const targetRect = handArea.getBoundingClientRect();

						// 执行动画
						anime({
						targets: cardElement,
						top: targetRect.top + 'px',
						left: targetRect.left + 'px',
						scale: [0.8, 1.2, 1],
						opacity: [0, 1, 1],
						duration: 1200,
						easing: 'easeInOutQuad',
						complete: () => {
						cardElement.remove();
						}
						});
						}

						// 切换开发者模式
						function toggleDevMode() {
						isDevMode = !isDevMode;
						document.getElementById('devModeToggle').textContent =
						isDevMode ? '开发者模式: 开启' : '开发者模式: 关闭';

						// 显示/隐藏开发者面板
						const devPanel = document.getElementById('devPanel');
						devPanel.style.display = isDevMode ? 'block' : 'none';

						log(`开发者模式 ${isDevMode ? '已开启' : '已关闭'}`);
						}</code>
				</div>
			</div>
			<div class="function-description">
				在测试模式下添加指定卡牌到手牌中。
			</div>

			<div class="css-section">
				<span class="css-name">
					配套CSS
					<div class="css-tooltip">
						<strong>开发者工具CSS</strong>
						<code>/* 开发者面板 */
							.dev-panel {
							position: fixed;
							top: 20px;
							right: 20px;
							background: rgba(0, 0, 0, 0.8);
							color: #00ff00;
							border-radius: 8px;
							padding: 15px;
							z-index: 2000;
							font-family: 'Consolas', 'Monaco', monospace;
							box-shadow: 0 0 15px rgba(0, 255, 0, 0.5);
							border: 1px solid #00ff00;
							max-width: 300px;
							display: none;
							}

							.dev-panel h3 {
							margin-top: 0;
							color: #00ff00;
							border-bottom: 1px solid #00ff00;
							padding-bottom: 8px;
							font-size: 18px;
							}

							/* 开发者模式切换按钮 */
							#devModeToggle {
							position: fixed;
							top: 20px;
							left: 20px;
							background: #333;
							color: #00ff00;
							border: 1px solid #00ff00;
							border-radius: 4px;
							padding: 8px 16px;
							font-family: 'Consolas', 'Monaco', monospace;
							cursor: pointer;
							z-index: 2000;
							transition: all 0.3s ease;
							}

							#devModeToggle:hover {
							background: #00ff00;
							color: #000;
							box-shadow: 0 0 15px rgba(0, 255, 0, 0.7);
							}

							/* 开发者控制项 */
							.dev-control {
							margin: 10px 0;
							display: flex;
							align-items: center;
							}

							.dev-control label {
							flex: 1;
							font-size: 14px;
							}

							.dev-control input,
							.dev-control select {
							background: #222;
							color: #00ff00;
							border: 1px solid #00ff00;
							border-radius: 4px;
							padding: 6px;
							width: 150px;
							font-family: 'Consolas', 'Monaco', monospace;
							}

							.dev-control button {
							background: #333;
							color: #00ff00;
							border: 1px solid #00ff00;
							border-radius: 4px;
							padding: 6px 12px;
							cursor: pointer;
							transition: all 0.3s ease;
							font-family: 'Consolas', 'Monaco', monospace;
							}

							.dev-control button:hover {
							background: #00ff00;
							color: #000;
							}

							/* 开发者卡牌添加动画 */
							.card.dev-card-addition {
							background: linear-gradient(45deg, #00ff00, #00cc00);
							color: black;
							font-weight: bold;
							border: 2px solid #00ff00;
							box-shadow: 0 0 20px rgba(0, 255, 0, 0.7);
							animation: devCardGlow 1.5s infinite alternate;
							}

							@keyframes devCardGlow {
							from {
							box-shadow: 0 0 10px rgba(0, 255, 0, 0.5);
							}
							to {
							box-shadow: 0 0 30px rgba(0, 255, 0, 0.9);
							}
							}

							/* 开发者模式下的特殊样式 */
							.dev-mode .card {
							border: 1px dashed rgba(0, 255, 0, 0.5);
							}

							.dev-mode .card:hover {
							border: 1px solid #00ff00;
							box-shadow: 0 0 15px rgba(0, 255, 0, 0.5);
							}

							/* 控制台样式 */
							.dev-console {
							background: #111;
							color: #00ff00;
							padding: 10px;
							border-radius: 4px;
							margin-top: 10px;
							max-height: 150px;
							overflow-y: auto;
							font-size: 12px;
							border: 1px solid #008800;
							}

							.dev-console::-webkit-scrollbar {
							width: 6px;
							}

							.dev-console::-webkit-scrollbar-thumb {
							background: #008800;
							border-radius: 3px;
							}

							/* 响应式设计 */
							@media (max-width: 768px) {
							.dev-panel {
							top: 10px;
							right: 10px;
							left: 10px;
							max-width: none;
							}

							#devModeToggle {
							top: 10px;
							left: 10px;
							}
							}</code>
					</div>
				</span>
			</div>

			<div class="key-points">
				<h3>关键技术点</h3>
				<ul>
					<li>开发者模式开关控制功能可见性</li>
					<li>终端风格UI设计（黑底绿字）</li>
					<li>卡牌添加动画增强视觉反馈</li>
					<li>安全边界检查防止非开发者使用</li>
					<li>浮动面板设计不干扰主游戏界面</li>
					<li>响应式布局适配不同屏幕尺寸</li>
					<li>动态卡牌生成确保唯一标识符</li>
				</ul>
			</div>
		</div>

		<!-- 用户界面系统 -->
		<div class="function-category">五、用户界面系统</div>

		<!-- 1. 导航系统 -->
		<div class="function-item">
			<div class="function-name">
				initializeButtons()
				<div class="function-tooltip">
					<strong>initializeButtons()</strong> - 初始化按钮事件
					<code>function initializeButtons() {
						// 核心游戏按钮
						document.getElementById('shuffleBtn').addEventListener('click', shuffleDeck);
						document.getElementById('drawBtn').addEventListener('click', () => drawCards(3));
						document.getElementById('endPhaseBtn').addEventListener('click', endPhase);

						// 特殊功能按钮
						document.getElementById('reshuffleBtn').addEventListener('click', handleReshuffle);
						document.getElementById('securityLogBtn').addEventListener('click', generateSecurityLog);

						// 开发者模式按钮
						document.getElementById('devModeToggle').addEventListener('click', toggleDevMode);

						// 卡牌操作按钮
						const cardButtons = document.querySelectorAll('.card-action');
						cardButtons.forEach(btn => {
						btn.addEventListener('click', function() {
						const cardId = this.dataset.cardId;
						const action = this.dataset.action;
						handleCardAction(cardId, action);
						});
						});

						// 阶段切换按钮
						const phaseButtons = document.querySelectorAll('.phase-btn');
						phaseButtons.forEach(btn => {
						btn.addEventListener('click', function() {
						const phase = this.dataset.phase;
						setPhase(phase);
						});
						});

						// 键盘快捷键
						document.addEventListener('keydown', handleKeyDown);

						log("按钮事件初始化完成");
						}

						// 键盘快捷键处理
						function handleKeyDown(event) {
						// 防止在输入框中触发
						if (event.target.tagName === 'INPUT') return;

						switch (event.key.toLowerCase()) {
						case 's':
						document.getElementById('shuffleBtn').click();
						break;
						case 'd':
						document.getElementById('drawBtn').click();
						break;
						case 'e':
						document.getElementById('endPhaseBtn').click();
						break;
						case 'r':
						document.getElementById('reshuffleBtn').click();
						break;
						case 'l':
						document.getElementById('securityLogBtn').click();
						break;
						case 'f1':
						document.getElementById('helpBtn').click();
						break;
						case 'escape':
						closeAllModals();
						break;
						}
						}

						// 卡牌操作处理
						function handleCardAction(cardId, action) {
						const card = hand.find(c => c.uid === cardId);
						if (!card) return;

						switch (action) {
						case 'use':
						useCard(card);
						break;
						case 'discard':
						discardCard(card);
						break;
						case 'equip':
						equipCard(card);
						break;
						}
						}

						// 关闭所有模态框
						function closeAllModals() {
						document.querySelectorAll('.modal').forEach(modal => {
						modal.style.display = 'none';
						});
						}</code>
				</div>
			</div>
			<div class="function-description">
				绑定所有按钮的点击事件处理函数，并设置键盘快捷键。
			</div>

			<div class="css-section">
				<span class="css-name">
					配套CSS
					<div class="css-tooltip">
						<strong>导航按钮CSS</strong>
						<code>/* 按钮容器 */
							.button-container {
							display: flex;
							flex-wrap: wrap;
							gap: 12px;
							margin: 20px 0;
							justify-content: center;
							padding: 15px;
							background: #f8f9fa;
							border-radius: 8px;
							border: 1px solid #e0e0e0;
							}

							/* 核心按钮样式 */
							.nav-button {
							padding: 12px 24px;
							background: linear-gradient(to bottom, #4CAF50, #2E7D32);
							color: white;
							border: none;
							border-radius: 6px;
							cursor: pointer;
							transition: all 0.3s ease;
							font-weight: bold;
							box-shadow: 0 4px 8px rgba(0,0,0,0.15);
							display: flex;
							align-items: center;
							justify-content: center;
							min-width: 120px;
							position: relative;
							overflow: hidden;
							}

							.nav-button:hover {
							transform: translateY(-3px);
							box-shadow: 0 6px 12px rgba(0,0,0,0.2);
							background: linear-gradient(to bottom, #66BB6A, #388E3C);
							}

							.nav-button:active {
							transform: translateY(1px);
							box-shadow: 0 2px 5px rgba(0,0,0,0.2);
							}

							/* 按钮波纹效果 */
							.nav-button::after {
							content: '';
							position: absolute;
							top: 50%;
							left: 50%;
							width: 0;
							height: 0;
							background: rgba(255, 255, 255, 0.3);
							border-radius: 50%;
							transform: translate(-50%, -50%);
							opacity: 0;
							}

							.nav-button:active::after {
							animation: ripple 0.6s linear;
							}

							@keyframes ripple {
							0% {
							width: 0;
							height: 0;
							opacity: 1;
							}
							100% {
							width: 300px;
							height: 300px;
							opacity: 0;
							}
							}

							/* 按钮图标 */
							.nav-button::before {
							margin-right: 8px;
							font-size: 18px;
							}

							#shuffleBtn::before {
							content: '🔀';
							}

							#drawBtn::before {
							content: '🃏';
							}

							#endPhaseBtn::before {
							content: '⏭️';
							}

							#reshuffleBtn::before {
							content: '🔄';
							}

							#securityLogBtn::before {
							content: '📝';
							}

							#helpBtn::before {
							content: '❓';
							}

							/* 按钮状态 */
							.nav-button.active {
							animation: buttonPulse 1.5s infinite;
							border: 2px solid #FFEB3B;
							}

							@keyframes buttonPulse {
							0% {
							box-shadow: 0 0 0 0 rgba(255, 235, 59, 0.7);
							}
							70% {
							box-shadow: 0 0 0 10px rgba(255, 235, 59, 0);
							}
							100% {
							box-shadow: 0 0 0 0 rgba(255, 235, 59, 0);
							}
							}

							.nav-button:disabled {
							opacity: 0.5;
							cursor: not-allowed;
							transform: none;
							box-shadow: none;
							}

							/* 卡牌操作按钮 */
							.card-action {
							padding: 8px 12px;
							background: rgba(255, 255, 255, 0.8);
							border: 1px solid #ddd;
							border-radius: 4px;
							cursor: pointer;
							transition: all 0.2s ease;
							font-size: 12px;
							margin: 4px;
							}

							.card-action:hover {
							background: rgba(255, 255, 255, 1);
							transform: translateY(-2px);
							box-shadow: 0 2px 5px rgba(0,0,0,0.1);
							}

							/* 按钮组 */
							.button-group {
							display: flex;
							gap: 8px;
							margin-top: 10px;
							}

							/* 响应式设计 */
							@media (max-width: 768px) {
							.button-container {
							flex-direction: column;
							align-items: center;
							}

							.nav-button {
							width: 100%;
							max-width: 300px;
							margin-bottom: 10px;
							}

							.button-group {
							flex-direction: column;
							}
							}</code>
					</div>
				</span>
			</div>

			<div class="key-points">
				<h3>关键技术点</h3>
				<ul>
					<li>统一事件绑定管理所有按钮交互</li>
					<li>键盘快捷键支持提升操作效率</li>
					<li>按钮波纹动画增强点击反馈</li>
					<li>悬停效果提升用户体验</li>
					<li>响应式布局适配不同屏幕尺寸</li>
					<li>状态指示器显示按钮激活状态</li>
					<li>禁用状态处理防止无效操作</li>
				</ul>
			</div>
		</div>

		<!-- 2. 响应式设计 -->
		<div class="function-item">
			<div class="function-name">
				updateTooltipAlignment()
				<div class="function-tooltip">
					<strong>updateTooltipAlignment()</strong> - 更新工具提示对齐
					<code>function updateTooltipAlignment() {
						// 获取所有工具提示元素
						const tooltips = document.querySelectorAll('.css-tooltip');

						// 遍历所有工具提示
						tooltips.forEach(tooltip => {
						const parent = tooltip.parentElement;
						const parentRect = parent.getBoundingClientRect();

						// 获取视口尺寸
						const viewportWidth = window.innerWidth;
						const viewportHeight = window.innerHeight;

						// 重置位置
						tooltip.style.left = '';
						tooltip.style.right = '';
						tooltip.style.top = '';
						tooltip.style.bottom = '';

						// 水平位置调整
						if (parentRect.left + tooltip.offsetWidth > viewportWidth - 20) {
						// 如果右边空间不足，显示在左侧
						tooltip.style.right = '100%';
						tooltip.style.left = 'auto';
						} else {
						// 默认显示在右侧
						tooltip.style.left = '0';
						tooltip.style.right = 'auto';
						}

						// 垂直位置调整
						if (parentRect.top - tooltip.offsetHeight < 20) { // 如果上方空间不足，显示在下方 tooltip.style.top='100%' ;
							tooltip.style.bottom='auto' ; } else { // 默认显示在上方 tooltip.style.bottom='100%' ;
							tooltip.style.top='auto' ; } }); // 添加箭头指示器 addTooltipArrows(); } // 添加工具提示箭头 function
							addTooltipArrows() { // 移除现有箭头 document.querySelectorAll('.tooltip-arrow').forEach(arrow=>
							arrow.remove());

							// 为每个工具提示添加箭头
							document.querySelectorAll('.css-tooltip').forEach(tooltip => {
							const arrow = document.createElement('div');
							arrow.className = 'tooltip-arrow';

							// 根据位置设置箭头方向
							if (tooltip.style.bottom === '100%') {
							// 上方提示框
							arrow.style.bottom = '-5px';
							arrow.style.borderTopColor = '#f8f9fa';
							} else {
							// 下方提示框
							arrow.style.top = '-5px';
							arrow.style.borderBottomColor = '#f8f9fa';
							}

							if (tooltip.style.left === '0') {
							// 右侧提示框
							arrow.style.left = '15px';
							} else {
							// 左侧提示框
							arrow.style.right = '15px';
							}

							tooltip.appendChild(arrow);
							});
							}

							// 初始化响应式布局
							function initResponsiveLayout() {
							// 初始调整
							updateTooltipAlignment();

							// 监听窗口大小变化
							window.addEventListener('resize', updateTooltipAlignment);

							// 监听滚动事件
							window.addEventListener('scroll', updateTooltipAlignment);

							log("响应式布局已初始化");
							}</code>
				</div>
			</div>
			<div class="function-description">
				根据屏幕尺寸和位置动态调整工具提示的位置和方向。
			</div>

			<div class="css-section">
				<span class="css-name">
					配套CSS
					<div class="css-tooltip">
						<strong>响应式设计CSS</strong>
						<code>/* 工具提示基础样式 */
							.css-tooltip {
							position: absolute;
							z-index: 1000;
							box-shadow: 0 6px 16px rgba(0,0,0,0.15);
							border: 1px solid #dadce0;
							border-radius: 8px;
							padding: 15px;
							background: #f8f9fa;
							color: #202124;
							font-family: 'Consolas', 'Monaco', monospace;
							font-size: 13px;
							line-height: 1.5;
							white-space: pre-wrap;
							overflow: auto;
							max-height: 400px;
							display: none;
							transition: opacity 0.3s ease, transform 0.3s ease;
							}

							/* 工具提示箭头 */
							.tooltip-arrow {
							position: absolute;
							width: 0;
							height: 0;
							border-style: solid;
							border-width: 5px;
							border-color: transparent transparent #f8f9fa transparent;
							}

							/* 响应式调整 */
							@media (max-width: 1200px) {
							.css-tooltip {
							max-width: 500px;
							}
							}

							@media (max-width: 992px) {
							.css-tooltip {
							max-width: 400px;
							font-size: 12px;
							padding: 12px;
							}
							}

							@media (max-width: 768px) {
							.css-tooltip {
							max-width: 90vw;
							left: 5vw !important;
							right: 5vw !important;
							transform: none !important;
							}

							/* 移动设备上固定位置 */
							.css-tooltip.mobile-position {
							position: fixed;
							top: 50% !important;
							left: 5% !important;
							right: 5% !important;
							bottom: auto !important;
							transform: translateY(-50%) !important;
							max-height: 70vh;
							}

							.tooltip-arrow {
							display: none;
							}
							}

							@media (max-width: 480px) {
							.css-tooltip {
							padding: 10px;
							font-size: 11px;
							}

							.css-tooltip code {
							padding: 10px;
							font-size: 10px;
							}
							}

							/* 工具提示显示动画 */
							.css-tooltip.showing {
							animation: tooltipAppear 0.3s ease forwards;
							display: block;
							opacity: 0;
							transform: translateY(10px);
							}

							@keyframes tooltipAppear {
							to {
							opacity: 1;
							transform: translateY(0);
							}
							}

							/* 方向箭头 */
							.tooltip-top .tooltip-arrow {
							bottom: -5px;
							left: 50%;
							transform: translateX(-50%);
							border-width: 5px 5px 0;
							border-color: #f8f9fa transparent transparent transparent;
							}

							.tooltip-bottom .tooltip-arrow {
							top: -5px;
							left: 50%;
							transform: translateX(-50%);
							border-width: 0 5px 5px;
							border-color: transparent transparent #f8f9fa transparent;
							}

							.tooltip-left .tooltip-arrow {
							right: -5px;
							top: 50%;
							transform: translateY(-50%);
							border-width: 5px 0 5px 5px;
							border-color: transparent transparent transparent #f8f9fa;
							}

							.tooltip-right .tooltip-arrow {
							left: -5px;
							top: 50%;
							transform: translateY(-50%);
							border-width: 5px 5px 5px 0;
							border-color: transparent #f8f9fa transparent transparent;
							}

							/* 触摸设备优化 */
							@media (hover: none) {
							.css-name:hover .css-tooltip {
							display: none;
							}

							.css-tooltip.mobile-tap {
							display: block;
							animation: tooltipAppear 0.3s ease forwards;
							}
							}</code>
					</div>
				</span>
			</div>

			<div class="key-points">
				<h3>关键技术点</h3>
				<ul>
					<li>动态位置计算确保工具提示始终可见</li>
					<li>边界检测防止工具提示超出视口</li>
					<li>响应式断点适配不同屏幕尺寸</li>
					<li>方向箭头指示工具提示来源</li>
					<li>平滑动画增强用户体验</li>
					<li>触摸设备特殊优化</li>
					<li>滚动和调整大小时自动更新位置</li>
				</ul>
			</div>
		</div>

		<!-- 3. 动画与反馈 -->
		<div class="function-item">
			<div class="function-name">
				highlightCard(cardElement)
				<div class="function-tooltip">
					<strong>highlightCard(cardElement)</strong> - 高亮卡牌
					<code>function highlightCard(cardElement) {
						// 移除现有高亮效果
						cardElement.classList.remove('card-highlight');

						// 触发重排以重置动画
						void cardElement.offsetWidth;

						// 添加高亮类
						cardElement.classList.add('card-highlight');

						// 添加粒子效果
						createHighlightParticles(cardElement);

						// 3秒后移除高亮效果
						setTimeout(() => {
						cardElement.classList.remove('card-highlight');
						}, 3000);
						}

						// 创建高亮粒子效果
						function createHighlightParticles(cardElement) {
						const rect = cardElement.getBoundingClientRect();
						const particleContainer = document.getElementById('particle-container');

						// 创建粒子数量
						const particleCount = 30;

						for (let i = 0; i < particleCount; i++) { const particle=document.createElement('div');
							particle.className='highlight-particle' ; // 随机位置 const x=rect.left + Math.random() *
							rect.width; const y=rect.top + Math.random() * rect.height; particle.style.left=`${x}px`;
							particle.style.top=`${y}px`; // 随机颜色 const colors=['#ffeb3b', '#4caf50' , '#2196f3'
							, '#f44336' ]; const color=colors[Math.floor(Math.random() * colors.length)];
							particle.style.backgroundColor=color; // 随机大小 const size=3 + Math.random() * 5;
							particle.style.width=`${size}px`; particle.style.height=`${size}px`;
							particleContainer.appendChild(particle); // 粒子动画 anime({ targets: particle, translateX: ()=>
							anime.random(-100, 100),
							translateY: () => anime.random(-100, 100),
							scale: [1, 0],
							opacity: [1, 0],
							duration: 1000 + Math.random() * 1000,
							easing: 'easeOutExpo',
							complete: () => {
							particle.remove();
							}
							});
							}
							}</code>
				</div>
			</div>
			<div class="function-description">
				为指定卡牌添加高亮效果，提供视觉反馈。
			</div>

			<div class="css-section">
				<span class="css-name">
					配套CSS
					<div class="css-tooltip">
						<strong>高亮动画CSS</strong>
						<code>/* 卡牌高亮效果 */
							.card-highlight {
							animation: cardHighlight 3s ease-in-out;
							z-index: 100;
							position: relative;
							}

							@keyframes cardHighlight {
							0% {
							transform: scale(1);
							box-shadow: 0 0 0 rgba(255, 235, 59, 0);
							}
							25% {
							transform: scale(1.1);
							box-shadow: 0 0 20px rgba(255, 235, 59, 0.8);
							}
							50% {
							transform: scale(1.05);
							box-shadow: 0 0 30px rgba(255, 235, 59, 0.9);
							}
							75% {
							transform: scale(1.08);
							box-shadow: 0 0 25px rgba(255, 235, 59, 0.7);
							}
							100% {
							transform: scale(1);
							box-shadow: 0 0 0 rgba(255, 235, 59, 0);
							}
							}

							/* 高亮粒子 */
							.highlight-particle {
							position: absolute;
							border-radius: 50%;
							pointer-events: none;
							z-index: 2000;
							}

							/* 粒子容器 */
							#particle-container {
							position: fixed;
							top: 0;
							left: 0;
							width: 100%;
							height: 100%;
							pointer-events: none;
							z-index: 1500;
							overflow: hidden;
							}

							/* 特殊卡牌类型的高亮 */
							.card[data-card-type="kill"].card-highlight {
							animation: killHighlight 3s ease-in-out;
							}

							@keyframes killHighlight {
							0% {
							box-shadow: 0 0 0 rgba(244, 67, 54, 0);
							}
							50% {
							box-shadow: 0 0 30px rgba(244, 67, 54, 0.8);
							}
							100% {
							box-shadow: 0 0 0 rgba(244, 67, 54, 0);
							}
							}

							.card[data-card-type="dodge"].card-highlight {
							animation: dodgeHighlight 3s ease-in-out;
							}

							@keyframes dodgeHighlight {
							0% {
							box-shadow: 0 0 0 rgba(33, 150, 243, 0);
							}
							50% {
							box-shadow: 0 0 30px rgba(33, 150, 243, 0.8);
							}
							100% {
							box-shadow: 0 0 0 rgba(33, 150, 243, 0);
							}
							}

							/* 悬停高亮效果 */
							.card:hover:not(.disabled) {
							transform: translateY(-8px);
							box-shadow: 0 12px 20px rgba(0, 0, 0, 0.2);
							z-index: 50;
							transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
							}

							/* 减少运动偏好设置 */
							@media (prefers-reduced-motion: reduce) {
							.card-highlight {
							animation: none !important;
							box-shadow: 0 0 10px rgba(255, 235, 59, 0.7) !important;
							}

							.highlight-particle {
							display: none;
							}

							.card:hover:not(.disabled) {
							transform: translateY(-4px);
							transition: none;
							}
							}</code>
					</div>
				</span>
			</div>

			<div class="key-points">
				<h3>关键技术点</h3>
				<ul>
					<li>多阶段动画增强视觉冲击力</li>
					<li>动态粒子效果提升视觉反馈</li>
					<li>基于卡牌类型的差异化高亮效果</li>
					<li>性能优化（使用transform和opacity）</li>
					<li>支持减少运动偏好设置（prefers-reduced-motion）</li>
					<li>悬停效果增强交互体验</li>
					<li>层级管理确保正确显示顺序</li>
				</ul>
			</div>
		</div>

		<!-- 更新日志系统 -->
		<div class="function-category">六、更新日志系统</div>

		<!-- 1. 日志页面设计 -->
		<div class="function-item">
			<div class="function-name">
				renderVersionList(versions)
				<div class="function-tooltip">
					<strong>renderVersionList(versions)</strong> - 渲染版本列表
					<code>function renderVersionList(versions) {
						const container = document.getElementById('version-history');
						container.innerHTML = '';

						// 按日期降序排序
						versions.sort((a, b) => new Date(b.date) - new Date(a.date));

						// 创建时间线容器
						const timeline = document.createElement('div');
						timeline.className = 'version-timeline';

						versions.forEach(version => {
						// 创建版本条目
						const versionItem = document.createElement('div');
						versionItem.className = 'version-item';

						// 创建版本头
						const header = document.createElement('div');
						header.className = 'version-header';

						const versionBadge = document.createElement('span');
						versionBadge.className = 'version-badge';
						versionBadge.textContent = version.version;

						const dateBadge = document.createElement('span');
						dateBadge.className = 'date-badge';
						dateBadge.textContent = new Date(version.date).toLocaleDateString();

						header.appendChild(versionBadge);
						header.appendChild(dateBadge);

						// 创建更新内容
						const content = document.createElement('div');
						content.className = 'version-content';

						if (version.changes && version.changes.length > 0) {
						const changeList = document.createElement('ul');
						changeList.className = 'change-list';

						version.changes.forEach(change => {
						const changeItem = document.createElement('li');
						changeItem.className = `change-item change-${change.type || 'feature'}`;

						const changeIcon = document.createElement('span');
						changeIcon.className = 'change-icon';
						changeIcon.textContent = change.type === 'fix' ? '🐞' :
						change.type === 'improvement' ? '⚡' : '✨';

						const changeText = document.createElement('span');
						changeText.className = 'change-text';
						changeText.textContent = change.description;

						changeItem.appendChild(changeIcon);
						changeItem.appendChild(changeText);
						changeList.appendChild(changeItem);
						});

						content.appendChild(changeList);
						}

						// 添加版本条目
						versionItem.appendChild(header);
						versionItem.appendChild(content);
						timeline.appendChild(versionItem);
						});

						container.appendChild(timeline);
						}</code>
				</div>
			</div>
			<div class="function-description">
				将版本更新数据渲染为时间线样式的可视化列表。
			</div>

			<div class="css-section">
				<span class="css-name">
					配套CSS
					<div class="css-tooltip">
						<strong>日志页面CSS</strong>
						<code>/* 版本历史容器 */
							#version-history {
							max-width: 800px;
							margin: 0 auto;
							padding: 20px;
							}

							/* 时间线样式 */
							.version-timeline {
							position: relative;
							padding-left: 30px;
							border-left: 3px solid #e0e0e0;
							margin-left: 15px;
							}

							.version-timeline::before {
							content: '';
							position: absolute;
							top: 0;
							left: -8px;
							width: 16px;
							height: 16px;
							border-radius: 50%;
							background: #2196F3;
							z-index: 1;
							}

							.version-timeline::after {
							content: '';
							position: absolute;
							bottom: 0;
							left: -8px;
							width: 16px;
							height: 16px;
							border-radius: 50%;
							background: #4CAF50;
							z-index: 1;
							}

							/* 版本条目 */
							.version-item {
							position: relative;
							margin-bottom: 30px;
							padding: 20px;
							background: white;
							border-radius: 8px;
							box-shadow: 0 3px 10px rgba(0,0,0,0.08);
							transition: all 0.3s ease;
							}

							.version-item:hover {
							transform: translateY(-5px);
							box-shadow: 0 5px 15px rgba(0,0,0,0.1);
							}

							.version-item::before {
							content: '';
							position: absolute;
							top: 24px;
							left: -33px;
							width: 12px;
							height: 12px;
							border-radius: 50%;
							background: #2196F3;
							border: 3px solid white;
							z-index: 2;
							}

							/* 版本头 */
							.version-header {
							display: flex;
							align-items: center;
							margin-bottom: 15px;
							padding-bottom: 10px;
							border-bottom: 1px solid #f0f0f0;
							}

							.version-badge {
							background: #2196F3;
							color: white;
							padding: 5px 12px;
							border-radius: 20px;
							font-weight: bold;
							font-size: 16px;
							margin-right: 15px;
							}

							.date-badge {
							background: #f5f5f5;
							color: #666;
							padding: 4px 10px;
							border-radius: 4px;
							font-size: 14px;
							}

							/* 更新内容 */
							.change-list {
							list-style: none;
							padding: 0;
							margin: 0;
							}

							.change-item {
							padding: 8px 0;
							display: flex;
							align-items: flex-start;
							}

							.change-icon {
							margin-right: 10px;
							font-size: 18px;
							min-width: 24px;
							text-align: center;
							}

							.change-text {
							flex: 1;
							line-height: 1.5;
							}

							/* 不同类型的更新 */
							.change-feature .change-icon {
							color: #4CAF50;
							}

							.change-fix .change-icon {
							color: #F44336;
							}

							.change-improvement .change-icon {
							color: #FF9800;
							}

							/* 动画效果 */
							.version-item {
							animation: fadeInUp 0.6s ease forwards;
							opacity: 0;
							transform: translateY(20px);
							}

							@keyframes fadeInUp {
							to {
							opacity: 1;
							transform: translateY(0);
							}
							}

							.version-item:nth-child(1) { animation-delay: 0.1s; }
							.version-item:nth-child(2) { animation-delay: 0.2s; }
							.version-item:nth-child(3) { animation-delay: 0.3s; }
							.version-item:nth-child(4) { animation-delay: 0.4s; }

							/* 响应式设计 */
							@media (max-width: 768px) {
							.version-timeline {
							padding-left: 20px;
							margin-left: 10px;
							}

							.version-item::before {
							left: -28px;
							}

							.version-header {
							flex-direction: column;
							align-items: flex-start;
							}

							.date-badge {
							margin-top: 8px;
							}
							}

							@media (max-width: 480px) {
							.version-item {
							padding: 15px;
							}

							.version-badge {
							font-size: 14px;
							}

							.change-item {
							font-size: 14px;
							}
							}</code>
					</div>
				</span>
			</div>

			<div class="key-points">
				<h3>关键技术点</h3>
				<ul>
					<li>时间线布局直观展示版本历史</li>
					<li>交互动画增强用户体验</li>
					<li>按更新类型分类展示（功能/修复/优化）</li>
					<li>响应式设计适配不同屏幕尺寸</li>
					<li>渐进式动画效果提升视觉体验</li>
					<li>悬停效果提供视觉反馈</li>
					<li>语义化图标增强可读性</li>
				</ul>
			</div>
		</div>

		<!-- 辅助工具组件 -->
		<div class="function-category">七、辅助工具组件</div>

		<!-- 1. 工具提示系统 -->
		<div class="function-item">
			<div class="function-name">
				showTooltip(element, content)
				<div class="function-tooltip">
					<strong>showTooltip(element, content)</strong> - 显示工具提示
					<code>function showTooltip(element, content) {
						// 检查是否已存在工具提示
						const existingTooltip = document.getElementById('custom-tooltip');
						if (existingTooltip) existingTooltip.remove();

						// 创建工具提示元素
						const tooltip = document.createElement('div');
						tooltip.id = 'custom-tooltip';
						tooltip.className = 'tooltip';
						tooltip.innerHTML = content;

						// 添加到DOM
						document.body.appendChild(tooltip);

						// 获取元素位置
						const rect = element.getBoundingClientRect();
						const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
						const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;

						// 计算位置（避免超出视口）
						let top = rect.top + scrollTop - tooltip.offsetHeight - 10;
						let left = rect.left + scrollLeft + rect.width / 2 - tooltip.offsetWidth / 2;

						// 边界检查
						if (top < 10) top=rect.bottom + scrollTop + 10; if (left < 10) left=10; if (left +
							tooltip.offsetWidth> window.innerWidth - 10) {
							left = window.innerWidth - tooltip.offsetWidth - 10;
							}

							// 设置位置
							tooltip.style.top = `${top}px`;
							tooltip.style.left = `${left}px`;

							// 添加箭头
							const arrow = document.createElement('div');
							arrow.className = 'tooltip-arrow';
							tooltip.appendChild(arrow);

							// 设置箭头方向
							if (top > rect.top + scrollTop) {
							// 工具提示在下方
							arrow.style.top = '-10px';
							arrow.style.borderBottomColor = '#333';
							} else {
							// 工具提示在上方
							arrow.style.bottom = '-10px';
							arrow.style.borderTopColor = '#333';
							}

							// 添加显示动画
							tooltip.style.opacity = '0';
							tooltip.style.transform = 'translateY(10px)';

							setTimeout(() => {
							tooltip.style.transition = 'opacity 0.3s, transform 0.3s';
							tooltip.style.opacity = '1';
							tooltip.style.transform = 'translateY(0)';
							}, 10);

							// 返回工具提示元素以便后续操作
							return tooltip;
							}

							// 隐藏工具提示
							function hideTooltip() {
							const tooltip = document.getElementById('custom-tooltip');
							if (tooltip) {
							tooltip.style.opacity = '0';
							tooltip.style.transform = 'translateY(10px)';

							setTimeout(() => {
							tooltip.remove();
							}, 300);
							}
							}

							// 自动绑定工具提示
							function bindTooltips() {
							const tooltipElements = document.querySelectorAll('[data-tooltip]');

							tooltipElements.forEach(el => {
							const content = el.dataset.tooltip;

							el.addEventListener('mouseenter', () => {
							showTooltip(el, content);
							});

							el.addEventListener('mouseleave', hideTooltip);
							el.addEventListener('click', hideTooltip);
							});
							}</code>
				</div>
			</div>
			<div class="function-description">
				在指定元素附近显示自定义内容的工具提示。
			</div>

			<div class="css-section">
				<span class="css-name">
					配套CSS
					<div class="css-tooltip">
						<strong>工具提示CSS</strong>
						<code>/* 工具提示基础样式 */
							.tooltip {
							position: absolute;
							z-index: 1000;
							background: #333;
							color: white;
							padding: 12px 16px;
							border-radius: 6px;
							font-size: 14px;
							line-height: 1.5;
							max-width: 300px;
							box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
							pointer-events: none;
							transform-origin: center bottom;
							}

							/* 工具提示箭头 */
							.tooltip-arrow {
							position: absolute;
							width: 0;
							height: 0;
							border-style: solid;
							border-width: 10px;
							border-color: transparent;
							left: 50%;
							transform: translateX(-50%);
							}

							/* 工具提示内容 */
							.tooltip-content {
							position: relative;
							z-index: 2;
							}

							/* 工具提示标题 */
							.tooltip-title {
							font-weight: bold;
							margin-bottom: 8px;
							font-size: 16px;
							color: #ffd700;
							display: flex;
							align-items: center;
							}

							.tooltip-title::before {
							content: 'ℹ️';
							margin-right: 8px;
							}

							/* 工具提示代码块 */
							.tooltip code {
							background: rgba(255, 255, 255, 0.1);
							padding: 2px 6px;
							border-radius: 4px;
							font-family: 'Consolas', monospace;
							display: inline-block;
							margin: 4px 0;
							}

							/* 工具提示动画 */
							.tooltip-enter {
							animation: tooltipFadeIn 0.3s ease forwards;
							}

							@keyframes tooltipFadeIn {
							from {
							opacity: 0;
							transform: translateY(10px);
							}
							to {
							opacity: 1;
							transform: translateY(0);
							}
							}

							.tooltip-exit {
							animation: tooltipFadeOut 0.2s ease forwards;
							}

							@keyframes tooltipFadeOut {
							from {
							opacity: 1;
							transform: translateY(0);
							}
							to {
							opacity: 0;
							transform: translateY(10px);
							}
							}

							/* 主题变体 */
							.tooltip-info {
							background: #3498db;
							}

							.tooltip-warning {
							background: #f39c12;
							}

							.tooltip-error {
							background: #e74c3c;
							}

							.tooltip-success {
							background: #2ecc71;
							}

							/* 响应式调整 */
							@media (max-width: 768px) {
							.tooltip {
							max-width: 250px;
							font-size: 13px;
							padding: 10px 14px;
							}

							.tooltip-title {
							font-size: 15px;
							}
							}

							/* 触摸设备优化 */
							@media (hover: none) {
							.tooltip {
							display: none;
							}

							.mobile-tooltip {
							position: fixed;
							bottom: 20px;
							left: 20px;
							right: 20px;
							max-width: none;
							display: block !important;
							animation: mobileTooltipAppear 0.4s ease;
							}

							@keyframes mobileTooltipAppear {
							from {
							transform: translateY(100%);
							opacity: 0;
							}
							to {
							transform: translateY(0);
							opacity: 1;
							}
							}
							}</code>
					</div>
				</span>
			</div>

			<div class="key-points">
				<h3>关键技术点</h3>
				<ul>
					<li>动态位置计算确保工具提示始终可见</li>
					<li>边界检测防止工具提示超出视口</li>
					<li>平滑动画增强用户体验</li>
					<li>方向箭头指示工具提示来源</li>
					<li>响应式设计适配不同屏幕尺寸</li>
					<li>触摸设备特殊优化</li>
					<li>多主题支持（信息/警告/错误/成功）</li>
				</ul>
			</div>
		</div>

		<!-- 2. 模态对话框系统 -->
		<div class="function-item">
			<div class="function-name">
				showModal(title, content)
				<div class="function-tooltip">
					<strong>showModal(title, content)</strong> - 显示模态对话框
					<code>function showModal(title, content) {
						// 关闭现有模态框
						closeAllModals();

						// 创建模态框容器
						const modal = document.createElement('div');
						modal.className = 'modal';
						modal.id = 'custom-modal';

						// 创建模态框内容
						modal.innerHTML = `
						<div class="modal-backdrop"></div>
						<div class="modal-container">
							<div class="modal-header">
								<h3 class="modal-title">${title}</h3>
								<button class="modal-close">&times;</button>
							</div>
							<div class="modal-content">${content}</div>
							<div class="modal-footer">
								<button class="modal-button confirm">确定</button>
								<button class="modal-button cancel">取消</button>
							</div>
						</div>
						`;

						// 添加到DOM
						document.body.appendChild(modal);

						// 添加事件监听器
						modal.querySelector('.modal-backdrop').addEventListener('click', closeAllModals);
						modal.querySelector('.modal-close').addEventListener('click', closeAllModals);
						modal.querySelector('.modal-button.confirm').addEventListener('click', closeAllModals);
						modal.querySelector('.modal-button.cancel').addEventListener('click', closeAllModals);

						// 添加动画效果
						setTimeout(() => {
						modal.classList.add('show');
						}, 10);

						// 阻止背景滚动
						document.body.style.overflow = 'hidden';

						return modal;
						}

						// 关闭所有模态框
						function closeAllModals() {
						const modals = document.querySelectorAll('.modal');
						modals.forEach(modal => {
						modal.classList.remove('show');

						// 添加关闭动画
						setTimeout(() => {
						modal.remove();
						}, 300);
						});

						// 恢复背景滚动
						document.body.style.overflow = '';
						}

						// 显示确认对话框
						function showConfirmModal(message, callback) {
						const modal = showModal('确认操作', `
						<div class="confirm-message">
							<div class="confirm-icon">⚠️</div>
							<p>${message}</p>
						</div>
						`);

						// 修改按钮行为
						modal.querySelector('.modal-button.confirm').addEventListener('click', () => {
						callback(true);
						closeAllModals();
						});

						modal.querySelector('.modal-button.cancel').addEventListener('click', () => {
						callback(false);
						closeAllModals();
						});

						return modal;
						}
					</code>
				</div>
			</div>
			<div class="function-description">
				显示带有标题和内容的模态对话框，支持确认和取消操作。
			</div>

			<div class="css-section">
				<span class="css-name">
					配套CSS
					<div class="css-tooltip">
						<strong>模态框CSS</strong>
						<code>/* 模态框基础样式 */
							.modal {
							position: fixed;
							top: 0;
							left: 0;
							right: 0;
							bottom: 0;
							z-index: 10000;
							display: flex;
							align-items: center;
							justify-content: center;
							opacity: 0;
							visibility: hidden;
							transition: opacity 0.3s ease, visibility 0.3s ease;
							}

							.modal.show {
							opacity: 1;
							visibility: visible;
							}

							/* 模态框背景 */
							.modal-backdrop {
							position: absolute;
							top: 0;
							left: 0;
							right: 0;
							bottom: 0;
							background: rgba(0, 0, 0, 0.7);
							backdrop-filter: blur(4px);
							}

							/* 模态框容器 */
							.modal-container {
							position: relative;
							background: white;
							border-radius: 12px;
							box-shadow: 0 20px 50px rgba(0, 0, 0, 0.3);
							width: 90%;
							max-width: 600px;
							max-height: 90vh;
							display: flex;
							flex-direction: column;
							z-index: 2;
							transform: translateY(30px);
							opacity: 0;
							transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
							}

							.modal.show .modal-container {
							transform: translateY(0);
							opacity: 1;
							}

							/* 模态框头部 */
							.modal-header {
							display: flex;
							justify-content: space-between;
							align-items: center;
							padding: 20px 25px;
							border-bottom: 1px solid #eee;
							}

							.modal-title {
							margin: 0;
							font-size: 22px;
							color: #333;
							}

							.modal-close {
							background: none;
							border: none;
							font-size: 28px;
							cursor: pointer;
							color: #999;
							transition: all 0.2s ease;
							line-height: 1;
							padding: 5px;
							}

							.modal-close:hover {
							color: #f44336;
							transform: scale(1.2);
							}

							/* 模态框内容 */
							.modal-content {
							padding: 25px;
							overflow-y: auto;
							flex: 1;
							max-height: 60vh;
							}

							/* 模态框页脚 */
							.modal-footer {
							display: flex;
							justify-content: flex-end;
							padding: 15px 25px;
							border-top: 1px solid #eee;
							gap: 15px;
							}

							.modal-button {
							padding: 10px 25px;
							border: none;
							border-radius: 6px;
							cursor: pointer;
							font-weight: bold;
							transition: all 0.2s ease;
							font-size: 16px;
							}

							.modal-button.confirm {
							background: #4CAF50;
							color: white;
							}

							.modal-button.cancel {
							background: #f5f5f5;
							color: #666;
							}

							.modal-button:hover {
							transform: translateY(-2px);
							box-shadow: 0 4px 8px rgba(0,0,0,0.1);
							}

							.modal-button.confirm:hover {
							background: #388E3C;
							}

							.modal-button.cancel:hover {
							background: #e0e0e0;
							}

							/* 确认对话框样式 */
							.confirm-message {
							display: flex;
							align-items: center;
							gap: 20px;
							}

							.confirm-icon {
							font-size: 48px;
							flex-shrink: 0;
							}

							.confirm-message p {
							margin: 0;
							font-size: 18px;
							line-height: 1.6;
							}

							/* 动画效果 */
							@keyframes modalIn {
							from {
							opacity: 0;
							transform: translateY(50px) scale(0.95);
							}
							to {
							opacity: 1;
							transform: translateY(0) scale(1);
							}
							}

							@keyframes modalOut {
							from {
							opacity: 1;
							transform: translateY(0) scale(1);
							}
							to {
							opacity: 0;
							transform: translateY(50px) scale(0.95);
							}
							}

							/* 响应式设计 */
							@media (max-width: 768px) {
							.modal-container {
							width: 95%;
							}

							.modal-header {
							padding: 15px 20px;
							}

							.modal-title {
							font-size: 20px;
							}

							.modal-content {
							padding: 20px;
							}

							.modal-footer {
							padding: 12px 20px;
							}

							.confirm-message {
							flex-direction: column;
							text-align: center;
							}
							}

							@media (max-width: 480px) {
							.modal-title {
							font-size: 18px;
							}

							.modal-content {
							padding: 15px;
							}

							.modal-button {
							padding: 8px 20px;
							font-size: 14px;
							}
							}</code>
					</div>
				</span>
			</div>

			<div class="key-points">
				<h3>关键技术点</h3>
				<ul>
					<li>平滑的进入/退出动画增强用户体验</li>
					<li>背景模糊效果提升视觉层次感</li>
					<li>响应式设计适配不同屏幕尺寸</li>
					<li>滚动锁定防止背景内容滚动</li>
					<li>确认对话框专用样式</li>
					<li>按钮悬停效果提供视觉反馈</li>
					<li>无障碍关闭选项（ESC键关闭）</li>
				</ul>
			</div>
		</div>

		<!-- 性能优化 -->
		<div class="function-category">八、性能优化</div>

		<!-- 1. 渲染优化 -->
		<div class="function-item">
			<div class="function-name">
				optimizeCardRendering()
				<div class="function-tooltip">
					<strong>optimizeCardRendering()</strong> - 优化卡牌渲染
					<code>function optimizeCardRendering() {
						// 获取卡牌容器
						const cardContainer = document.getElementById('card-container');

						// 创建虚拟滚动容器
						const virtualContainer = document.createElement('div');
						virtualContainer.id = 'virtual-card-container';
						virtualContainer.className = 'virtual-scroll-container';

						// 计算可见区域高度
						const containerHeight = cardContainer.clientHeight;
						const cardHeight = 150; // 卡牌高度（含间距）

						// 计算可见卡牌数量
						const visibleCards = Math.ceil(containerHeight / cardHeight) + 2;

						// 设置占位容器高度
						virtualContainer.style.height = `${allCards.length * cardHeight}px`;

						// 添加虚拟容器
						cardContainer.appendChild(virtualContainer);

						// 初始渲染
						renderVisibleCards(0);

						// 添加滚动事件监听
						cardContainer.addEventListener('scroll', handleCardScroll);

						log("卡牌渲染优化已启用，使用虚拟滚动技术");
						}

						// 渲染可见卡牌
						function renderVisibleCards(scrollTop) {
						const container = document.getElementById('virtual-card-container');
						const cardHeight = 150;
						const startIndex = Math.floor(scrollTop / cardHeight);
						const endIndex = startIndex + Math.ceil(container.clientHeight / cardHeight) + 2;

						// 清空容器
						container.innerHTML = '';

						// 渲染可见卡牌
						for (let i = startIndex; i < Math.min(endIndex, allCards.length); i++) { const card=allCards[i];
							const cardElement=createCardElement(card); // 设置位置 cardElement.style.position='absolute' ;
							cardElement.style.top=`${i * cardHeight}px`; container.appendChild(cardElement); } } //
							滚动事件处理 function handleCardScroll() { const
							container=document.getElementById('card-container');
							renderVisibleCards(container.scrollTop); } // 创建卡牌元素（优化版） function createCardElement(card) {
							// 使用文档片段减少重排 const fragment=document.createDocumentFragment(); // 创建卡牌容器 const
							cardElement=document.createElement('div'); cardElement.className='card virtual-card' ;
							cardElement.dataset.id=card.id; // 使用CSS变量存储卡牌数据
							cardElement.style.setProperty('--card-color', card.color);
							cardElement.style.setProperty('--card-type', card.type); // 添加基础内容 cardElement.innerHTML=`
							<div class="card-header">
							<span class="card-name">${card.name}</span>
							<span class="card-cost">${card.cost}</span>
				</div>
				<div class="card-image"></div>
				<div class="card-description">${card.description}</div>
				`;

				// 使用will-change优化动画
				cardElement.style.willChange = 'transform, opacity';

				// 添加到文档片段
				fragment.appendChild(cardElement);

				return fragment;
				}

				// 使用Intersection Observer延迟加载图片
				function initLazyLoading() {
				const observer = new IntersectionObserver((entries) => {
				entries.forEach(entry => {
				if (entry.isIntersecting) {
				const card = entry.target;
				const cardId = card.dataset.id;
				const cardData = allCards.find(c => c.id === cardId);

				// 加载图片
				const img = card.querySelector('.card-image');
				img.style.backgroundImage = `url(${cardData.image})`;

				// 停止观察
				observer.unobserve(card);
				}
				});
				}, { threshold: 0.1 });

				// 观察所有卡牌
				document.querySelectorAll('.virtual-card').forEach(card => {
				observer.observe(card);
				});
				}</code>
			</div>
		</div>
		<div class="function-description">
			使用虚拟滚动技术优化大量卡牌的渲染性能。
		</div>

		<div class="css-section">
			<span class="css-name">
				配套CSS
				<div class="css-tooltip">
					<strong>渲染优化CSS</strong>
					<code>/* 虚拟滚动容器 */
						.virtual-scroll-container {
						position: relative;
						width: 100%;
						overflow: hidden;
						}

						/* 优化后的卡牌样式 */
						.virtual-card {
						position: absolute;
						width: 100%;
						height: 140px;
						margin-bottom: 10px;
						background: white;
						border-radius: 8px;
						box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1);
						transition: transform 0.3s ease, box-shadow 0.3s ease;
						will-change: transform, box-shadow;
						overflow: hidden;
						display: flex;
						flex-direction: column;
						border: 1px solid #eee;
						}

						/* 卡牌头部 */
						.card-header {
						display: flex;
						justify-content: space-between;
						padding: 10px 15px;
						background: var(--card-color, #f5f5f5);
						border-bottom: 1px solid #e0e0e0;
						}

						.card-name {
						font-weight: bold;
						font-size: 16px;
						color: #333;
						}

						.card-cost {
						background: white;
						width: 24px;
						height: 24px;
						border-radius: 50%;
						display: flex;
						align-items: center;
						justify-content: center;
						font-weight: bold;
						box-shadow: 0 2px 4px rgba(0,0,0,0.1);
						}

						/* 卡牌图片 */
						.card-image {
						height: 70px;
						background-color: #f9f9f9;
						background-size: cover;
						background-position: center;
						flex-shrink: 0;
						}

						/* 卡牌描述 */
						.card-description {
						padding: 10px 15px;
						font-size: 13px;
						line-height: 1.4;
						color: #555;
						flex-grow: 1;
						overflow: hidden;
						text-overflow: ellipsis;
						display: -webkit-box;
						-webkit-line-clamp: 2;
						-webkit-box-orient: vertical;
						}

						/* 性能优化属性 */
						.virtual-card {
						contain: strict;
						content-visibility: auto;
						}

						/* 卡牌加载状态 */
						.card-image.loading {
						background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
						background-size: 200% 100%;
						animation: loadingAnimation 1.5s infinite;
						}

						@keyframes loadingAnimation {
						0% {
						background-position: 200% 0;
						}
						100% {
						background-position: -200% 0;
						}
						}

						/* 减少运动偏好设置 */
						@media (prefers-reduced-motion: reduce) {
						.virtual-card {
						transition: none;
						}
						}

						/* 打印样式优化 */
						@media print {
						.virtual-scroll-container {
						height: auto !important;
						}

						.virtual-card {
						position: static;
						page-break-inside: avoid;
						}
						}</code>
				</div>
			</span>
		</div>

		<div class="key-points">
			<h3>关键技术点</h3>
			<ul>
				<li>虚拟滚动技术减少DOM节点数量</li>
				<li>Intersection Observer实现图片懒加载</li>
				<li>CSS Containment优化渲染性能</li>
				<li>will-change属性提示浏览器优化</li>
				<li>文档片段减少DOM操作</li>
				<li>内容可见性(content-visibility)优化渲染</li>
				<li>骨架屏提升加载体验</li>
			</ul>
		</div>
		</div>


		<footer class="site-footer">
			<div class="author-info">
				<p>
					作者： <a href="https://space.bilibili.com/87412647?spm_id_from=333.1007.0.0"
						target="_blank">bilibili月が綺麗ですね_</a><br />
					联系方式：<a href="mailto:3099637681@qq.com" target="_blank">3099637681@qq.com（QQ同号）</a><br />
					有什么新功能或建议欢迎骚扰（著名来意）<br />
					<a href="https://1145141919810tonny.github.io/sgsmoniqi/" target="_blank">点击此处使用GitHub Pages在线服务</a>
				</p>
			</div>
			<div class="code-update">
				<a href="https://www.bilibili.com/read/readlist/rl929858?spm_id_from=333.1387.0.0" target="_blank"
					class="bili-btn" rel="noopener noreferrer">
					[bilibili]获取更新动态
				</a>
				<a href="https://github.com/1145141919810TONNY/sgsmoniqi/" target="_blank" class="github-btn"
					rel="noopener noreferrer">
					[GitHub]获取后续代码更新
				</a>
				<a href="https://gitcode.com/TONNY114514/sgsmnq?source_module=search_project" target="_blank" class="gitcode-btn"
					rel="noopener noreferrer">
					[GitCode]获取后续代码更新(国内git)
				</a>
			</div>
			<div class="license-notice">
				<p>
					Copyright &copy; <span id="copyright-year">2025</span> bilibili 月が綺麗ですね_<br />
					Released under the
					<a href="MIT LICENSE.html" title="查看MIT许可证" class="license-link" target="_blank">
						MIT License
					</a>
				</p>
				<p class="i18n-annotation">
					(法律条款以英文版<a href="MIT LICENSE.html" target="_blank">LICENSE</a>文件为准)
				</p>
			</div>
		</footer>
	</body>
	<script>
		// 获取按钮
		const backToTopBtn = document.getElementById('backToTopBtn');

		// 滚动事件监听，控制按钮显示隐藏
		window.addEventListener('scroll', () => {
			if (window.scrollY > 200) { // 当滚动距离大于200时显示按钮
				backToTopBtn.style.display = 'block';
			} else {
				backToTopBtn.style.display = 'none';
			}
		});

		// 点击按钮回到顶部
		backToTopBtn.addEventListener('click', () => {
			window.scrollTo({
				top: 0,
				behavior: 'smooth' // 平滑滚动
			});
		});
	</script>
</html>
